#!/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.
"""Adds common command-line arguments to a provided argument parser."""

import argparse
import _env  # pylint: disable=unused-import
from starboard.tools import build
from starboard.tools import params
import starboard.tools.config
import starboard.tools.platform


def AddLoggingArguments(arg_parser, default='info'):
  """Adds the logging level configuration argument.

  Args:
    arg_parser: The argument parser to used for initialization.
    default: The default logging level to use. Valid values are: 'info',
      'debug', 'warning', 'error', and 'critical'.
  """
  arg_parser.add_argument(
      '--log_level',
      choices=['info', 'debug', 'warning', 'error', 'critical'],
      default=default,
      help='The minimum level a log statement must be to be output. This value '
      "is used to initialize the 'logging' module log level.")


def AddPlatformConfigArguments(arg_parser):
  """Adds the platform configuration arguments required for building."""
  AddLoggingArguments(arg_parser)
  default_config, default_platform = build.GetDefaultConfigAndPlatform()
  arg_parser.add_argument(
      '-p',
      '--platform',
      choices=starboard.tools.platform.GetAll(),
      default=default_platform,
      required=not default_platform,
      help="Device platform, eg 'linux-x64x11'. Requires that you have "
      'already run gyp_cobalt for the desired platform.')
  arg_parser.add_argument(
      '-c',
      '--config',
      choices=starboard.tools.config.GetAll(),
      default=default_config,
      required=not default_config,
      help="Build config (eg, 'qa' or 'devel')")
  arg_parser.add_argument(
      '-P',
      '--loader_platform',
      default=None,
      help='Specifies the platform to build the loader with. This flag is only '
      'relevant for Evergreen builds, and should be the platform you intend to '
      "run your tests on (eg 'linux-x64x11', or 'raspi-2'). Requires that "
      '--loader_config be given, and that you have already run gyp_cobalt for '
      'the desired loader platform.')
  arg_parser.add_argument(
      '-C',
      '--loader_config',
      default=None,
      help="Specifies the config to build the loader with (eg 'qa' or 'devel')."
      'This flag is only relevant for Evergreen builds, and requires that '
      '--loader_platform be given.')


def AddLauncherArguments(arg_parser):
  """Adds the platform configuration and device information arguments require by launchers."""
  AddPlatformConfigArguments(arg_parser)
  arg_parser.add_argument(
      '-d', '--device_id', help='Devkit or IP address for the target device.')
  arg_parser.add_argument(
      '--target_params',
      help='Command line arguments to pass to the executable.'
      ' Because different executables could have differing command'
      ' line syntax, list all arguments exactly as you would to the'
      ' executable between a set of double quotation marks.')
  arg_parser.add_argument(
      '-o',
      '--out_directory',
      help='Directory containing tool binaries or their components.'
      ' Automatically derived if absent.')
  arg_parser.add_argument(
      '-O',
      '--loader_out_directory',
      default=None,
      help='Identical to --out_directory, except used for the loader platform '
      'when building and running in Evergreen mode.')


def CreatePlatformConfigParams(arg_parser=None):
  """Returns a PlatformConfigParams object initialized from an argument parser.

  This is a helper function that simplifies the creation of a
  PlatformConfigParams object. This function will create an argument parser if
  one is not provided, however if one is provided it is assumed that it has the
  necessary arguments added.

  Args:
    arg_parser: The argument parser to used for initialization. When |None| it
      will be created and initialized with the minimum required parameters.
  """
  if not arg_parser:
    arg_parser = argparse.ArgumentParser()
    AddPlatformConfigArguments(arg_parser)
  platform_config_params = params.PlatformConfigParams()
  _, _ = arg_parser.parse_known_args(namespace=platform_config_params)
  return platform_config_params


def CreateLauncherParams(arg_parser=None):
  """Returns a LauncherParams object initialized from an argument parser.

  This is a helper function that simplifies the creation of a LauncherParams
  object. This function will create an argument parser if one is not provided,
  however if one is provided it is assumed that it has the necessary arguments
  added.

  Args:
    arg_parser: The argument parser to used for initialization. When |None| it
      will be created and initialized with the minimum required parameters.
  """
  if not arg_parser:
    arg_parser = argparse.ArgumentParser()
    AddLauncherArguments(arg_parser)
  launcher_params = params.LauncherParams()
  args, _ = arg_parser.parse_known_args(namespace=launcher_params)
  if args.target_params is None:
    launcher_params.target_params = []
  else:
    launcher_params.target_params = args.target_params.split(' ')
  return launcher_params
