#!/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
from starboard.build.platforms import PLATFORMS
from starboard.tools import build
from starboard.tools import params
import starboard.tools.config


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=list(PLATFORMS.keys()),
      default=default_platform,
      required=not default_platform,
      help="Device platform, eg 'linux-x64x11'. Requires that you have "
      'already run gn.py 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 gn.py 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
