#!/usr/bin/python

# Copyright 2017 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 sys
import textwrap

import _env  # pylint: disable=unused-import
from starboard.build.gyp_runner import GypRunner
from starboard.tools import build
from starboard.tools import config
from starboard.tools import paths
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__))

  default_config, default_platform = build.GetDefaultConfigAndPlatform()
  parser.add_argument('-c', '--config', dest='build_configs', metavar='CONFIG',
                      action='append',
                      choices=config.GetAll(),
                      default=([default_config] if default_config
                               else 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()))
  parser.add_argument('-p', '--platform', choices=platform.GetAll(),
                      metavar='platform',
                      default=default_platform,
                      required=not default_platform,
                      help='Target platform. Supported platforms are: %s.' % (
                          _ListAsString(platform.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('-a', '--application',
                      metavar='application',
                      default='cobalt',
                      required=False,
                      help='The application being built, if any.')
  parser.add_argument('build_file', nargs='?',
                      default=None,
                      help='Root GYP build file. Default: starboard_all.gyp')

  return parser.parse_args(argv)


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 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

  try:
    gyp_runner = GypRunner(options)
  except RuntimeError as e:
    logging.exception('Failed to construct GypRunner.')
    return RETVAL_ERROR

  gyp_return = gyp_runner.BuildConfigs()
  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:]))
