#!/usr/bin/python

# Copyright 2017 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 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:]))
