#!/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 sys
import textwrap

import _env  # pylint: disable=unused-import
from cobalt.build import cobalt_configuration
from cobalt.build import gyp_utils
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 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',
      action='store_true',
      help='Enables verbose logging. For more control over the '
      "logging level use '--log_level' instead.")
  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.')

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

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


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

  build_id_server_url = os.environ.get('BUILD_ID_SERVER_URL')
  if build_id_server_url:
    options.build_number = gyp_utils.GetOrGenerateNewBuildNumber(
        version_server=build_id_server_url)
  else:
    options.build_number = gyp_utils.GetOrGenerateNewBuildNumber()

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