#!/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 command_line
from starboard.tools import config
from starboard.tools import log_level
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', action='store_true',
                      help='Enables verbose logging. For more control over the '
                      "logging level use '--log_level' instead.")
  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')

  command_line.AddLoggingArguments(parser, default='warning')

  return parser.parse_args(argv)


def main(argv):
  options = _ParseCommandLineArguments(argv)

  log_level.InitializeLogging(options)

  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:]))
