#!/usr/bin/env python
# Copyright 2014 The Cobalt Authors. 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 _env  # pylint: disable=unused-import
from cobalt.build import cobalt_configuration
from cobalt.build import gyp_utils
from cobalt.tools import paths
from starboard.build.gyp_runner import GypRunner
from starboard.tools import build
from starboard.tools import config
from starboard.tools import platform


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


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


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=config.GetAll(),
                      help='Specifies build configurations. Supported '
                      'configurations are %s. Can be specified multiple '
                      'times, creates all configurations if nothing is '
                      'given.' % _ListAsString(config.GetAll()))

  gyp_debug_options = build.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=platform.GetAll(),
                      metavar='platform',
                      help='Target platform. Supported platforms are: %s.' % (
                          _ListAsString(platform.GetAll())))
  parser.add_argument('build_file', nargs='?',
                      default=None,
                      help='GYP build file. Uses all.gyp if nothing is given.')

  options = parser.parse_args(argv)
  options.application = cobalt_configuration.APPLICATION_NAME
  return options


def _SetupLogging():
  logging_level = logging.WARNING
  logging_format = '%(message)s'
  logging.basicConfig(level=logging_level, format=logging_format)


def _SetLogLevel(verbose_count):
  logging_level = logging.WARNING
  if verbose_count == 1:
    logging_level = logging.INFO
  elif verbose_count >= 2:
    logging_level = logging.DEBUG
  logging.getLogger().setLevel(logging_level)

def _GetBuildConfigs(build_configs):
  if build_configs:
    return build_configs
  else:
    default_config, _ = build.GetDefaultConfigAndPlatform()
    if default_config:
      return default_config
    else:
      return config.GetAll()

def main(argv):
  _SetupLogging()
  options = _ParseCommandLineArguments(argv)
  _SetLogLevel(options.verbose_count)

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

  options.build_number = gyp_utils.GetBuildNumber()

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

  for config_name in _GetBuildConfigs(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:]))
