#!/usr/bin/env python
# Copyright 2014 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Wrapper to generate build files from .gyp files."""

import argparse
import logging
import os
import shlex
import sys
import textwrap

import bootstrap_path
import cobalt
from cobalt.build import config
from cobalt.build import gyp_utils
from cobalt.tools import paths


SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))

# Represents all valid build configurations.
VALID_BUILD_CONFIGS = config.VALID_BUILD_CONFIGS

# Represents all supported platforms.
VALID_PLATFORMS = config.VALID_PLATFORMS

# Return values used by main().
RETVAL_SUCCESS = 0
RETVAL_ERROR = 1

def _ListAsString(items):
  return ', '.join('"%s"' % x for x in items)


def _GetHostOS():
  """Returns the name of the hosting OS."""
  host_os_names = {
      'linux2': 'linux',
      'linux3': 'linux',
      'darwin': 'linux',
      'win32': 'win',
  }

  if not sys.platform in host_os_names:
    if sys.platform == 'cygwin':
       logging.error('There may be several incompatibilities when trying to\n'
                     'build from within cygwin. When using a bash shell is\n'
                     'preferred, consider using msysgit instead (see\n'
                     'https://msysgit.github.io).\n')
    raise RuntimeError('Unsupported platform: %s' % sys.platform)

  return host_os_names[sys.platform]


def _ParseCommandLineArguments(argv):
  """Parses command line arguments."""

  parser = argparse.ArgumentParser(
      formatter_class=argparse.RawDescriptionHelpFormatter,
      description=textwrap.dedent(__doc__))

  parser.add_argument('-C', '--config', dest='build_configs', metavar='CONFIG',
                      action='append', default=[],
                      choices=VALID_BUILD_CONFIGS,
                      help='Specifies build configurations. Supported '
                      'configurations are %s. Can be specified multiple '
                      'times, creates all configurations if nothing is '
                      'given.' % _ListAsString(VALID_BUILD_CONFIGS))

  gyp_debug_options = gyp_utils.GypDebugOptions()
  parser.add_argument('-D', '--debug', dest='debug', metavar='DEBUGMODE',
                      action='append', default=[],
                      choices=gyp_debug_options + ['all'],
                      help='Turn on a debugging mode for debugging GYP. '
                      'Supported modes are %s or "all" for all of '
                      'them.' % _ListAsString(gyp_debug_options))

  parser.add_argument('--check', action='store_true',
                      help='Check format of gyp files.')
  parser.add_argument('-v', '--verbose', dest='verbose_count',
                      default=0, action='count',
                      help='Verbose level (multiple times for more).')
  parser.add_argument('platform', choices=VALID_PLATFORMS,
                      metavar='platform',
                      help='Target platform. Supported platforms are: %s.' % (
                          _ListAsString(VALID_PLATFORMS)))
  parser.add_argument('build_file', nargs='?',
                      default=os.path.join(SCRIPT_DIR, 'all.gyp'),
                      help='GYP build file. Uses all.gyp if nothing is given.')

  options = parser.parse_args(argv)

  if options.build_configs:
    # Get rid of duplicates.
    options.build_configs = list(set(options.build_configs))
  else:
    options.build_configs = VALID_BUILD_CONFIGS

  return options


def _AppendIncludes(includes, args):
  for include in includes:
    args.append('-I{}'.format(include))


def _AppendVariables(variables, args):
  for var in variables:
    args.append('-D{}={}'.format(var, variables[var]))


def _AppendGeneratorVariables(variables, args):
  for var in variables:
    args.append('-G{}={}'.format(var, variables[var]))


def _SetupLogging(options):
  logging_level = logging.WARNING
  if options.verbose_count == 1:
    logging_level = logging.INFO
  elif options.verbose_count >= 2:
    logging_level = logging.DEBUG

  logging_format = '%(message)s'
  logging.basicConfig(level=logging_level,
                      format=logging_format)


class _GypRunner(object):
  """Responsible for running GYP."""

  def __init__(self, options):
    self.options = options
    self.common_args = []
    self.platform_config = config.LoadPlatformConfig(options.platform)
    if not self.platform_config:
      raise RuntimeError('Unable to load platform configuration.')

    os.environ.update(self.platform_config.GetEnvironmentVariables())
    self._MakeCommonArguments()

  def BuildConfig(self, config_name):
    """Builds the GYP file for a given config."""

    # Make a copy of the common arguments.
    args = self.common_args[:]

    variables = {
        # Add config specific variables.
        'cobalt_config': config_name,
        # Default deploy script. Certain platforms may choose to change this.
        'include_path_platform_deploy_gypi': 'starboard/build/deploy.gypi'
    }
    variables.update(self.platform_config.GetVariables(config_name))
    _AppendVariables(variables, args)

    # Add the symbolizer path for ASAN to allow translation of callstacks.
    asan_symbolizer_path = ''
    if variables.get('use_asan', 0) == 1:
      compiler_commandline = shlex.split(os.environ.get('CC', ''))
      for path in compiler_commandline:
        if os.path.isfile(path):
          test_path = os.path.join(os.path.dirname(path), 'llvm-symbolizer')
          if os.path.isfile(test_path):
            asan_symbolizer_path = test_path
            break
    asan_variables = {
      'asan_symbolizer_path': asan_symbolizer_path,
    }
    _AppendVariables(asan_variables, args)

    # Add config specific generator variables.
    generator_config = '{}_{}'.format(self.options.platform, config_name)

    generator_variables = {
        'config': generator_config,
    }
    generator_variables.update(
        self.platform_config.GetGeneratorVariables(config_name))
    _AppendGeneratorVariables(generator_variables, args)

    # That target build file goes last.
    args.append(self.options.build_file)

    gyp = gyp_utils.GetGyp()
    return gyp.main(args)

  def _MakeCommonArguments(self):
    """Makes a list of GYP arguments that is common to all configurations."""

    # Flavor will be used by the generator to figure out the target platform.
    flavor = self.platform_config.GetBuildFlavor()
    source_tree_dir = paths.REPOSITORY_ROOT
    self.common_args = [
        # Set the build format
        '--format={}-{}'.format(self.platform_config.GetBuildFormat(), flavor),
        # Set the depth argument to the top level directory. This will define
        # the DEPTH variable which is the relative path between the directory
        # containing the processed build file and the top level directory.
        '--depth={}'.format(source_tree_dir),
        # Set the top of the source tree.
        '--toplevel-dir={}'.format(source_tree_dir),
    ]

    # Add the source tree root to the Python path so that build files can
    # easily reference other build files in the source tree.
    sys.path.append(source_tree_dir)

    # Pass through the debug options.
    for debug in self.options.debug:
      self.common_args.append('--debug=%s' % debug)

    if self.options.check:
      self.common_args.append('--check')

    # Append GYP variables
    variables = {
        'OS': 'lb_shell',
        'cobalt_fastbuild': os.environ.get('LB_FASTBUILD', 0),
        'cobalt_version': gyp_utils.GetBuildNumber(),
        'host_os': _GetHostOS(),
        'CC_HOST': os.environ.get('CC_HOST', os.environ.get('CC','')),
    }
    if self.platform_config.IsStarboard():
      variables['OS'] = 'starboard'
      platform = self.platform_config.platform
      platforms = gyp_utils.GetAllPlatforms()
      if platform in platforms.keys():
        full_starboard_path = platforms[platform].path
        assert full_starboard_path[:len(source_tree_dir)] == source_tree_dir
        starboard_path = full_starboard_path[len(source_tree_dir) + 1:]
        starboard_path = starboard_path.replace(os.sep, '/')
        assert starboard_path[0] not in [ os.sep, os.altsep ]
        variables['starboard_path'] = starboard_path
    _AppendVariables(variables, self.common_args)

    # Append generator variables.
    generator_variables = {
        # set output folder name, affects all generators but MSVS
        'output_dir': 'out',
    }
    _AppendGeneratorVariables(generator_variables, self.common_args)

    # Append GYPI includes which will be includes by GYP before any processed
    # build file.
    gyp_includes = [
        os.path.join(SCRIPT_DIR, 'config', 'base.gypi'),
        # TODO: Consider removing dependency on common.gypi
        # going forward by moving the required bits into config/base.gypi.
        os.path.join(source_tree_dir, 'build', 'common.gypi'),
    ]
    gyp_includes.extend(self.platform_config.GetIncludes())
    _AppendIncludes(gyp_includes, self.common_args)


def main(argv):
  if os.environ.get('GYP_DEFINES'):
    logging.error('GYP_DEFINES environment variable is not supported.')
    return RETVAL_ERROR

  options = _ParseCommandLineArguments(argv)
  _SetupLogging(options)

  try:
    gyp_runner = _GypRunner(options)
  except RuntimeError as e:
    logging.error(e)
    return RETVAL_ERROR

  for config_name in options.build_configs:
    logging.info('Building config: %s.', config_name)
    gyp_return = gyp_runner.BuildConfig(config_name)
    if gyp_return:
      logging.error('Gyp failed with error code %d.', gyp_return)
      return gyp_return

  logging.info('Done.')
  return RETVAL_SUCCESS


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
