#!/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[:]

    # Add config specific variables.
    variables = {
        'cobalt_config': config_name,
    }
    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.GetThirdPartyPlatforms()
      if platform in platforms:
        full_starboard_path = platforms[platform]
        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:]))
