#!/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):
  arg_parser.add_argument(
      '--log_level',
      choices=['debug', 'warning', 'error', 'critical'],
      default='info',
      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
