#!/usr/bin/env python
# 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.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

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