#!/usr/bin/env python2
# 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:]))
