# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""The build API entry point."""

from __future__ import print_function

import os
import sys

from chromite.api import api_config as api_config_lib
from chromite.api import controller
from chromite.api import router as router_lib
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import tee
from chromite.utils import matching


def GetParser():
  """Build the argument parser."""
  parser = commandline.ArgumentParser(description=__doc__)

  call_group = parser.add_argument_group(
      'API Call Options',
      'These options are used to execute an endpoint. When making a call every '
      'argument in this group is required.')
  call_group.add_argument(
      'service_method',
      nargs='?',
      help='The "chromite.api.Service/Method" that is being called.')
  call_group.add_argument(
      '--input-json',
      type='path',
      help='Path to the JSON serialized input argument protobuf message.')
  call_group.add_argument(
      '--output-json',
      type='path',
      help='The path to which the result protobuf message should be written.')
  call_group.add_argument(
      '--tee-log',
      type='path',
      help='The path to which stdout and stderr should be teed to.')

  ux_group = parser.add_argument_group('Developer Options',
                                       'Options to help developers.')
  # Lists the full chromite.api.Service/Method, has both names to match
  # whichever mental model people prefer.
  ux_group.add_argument(
      '--list-methods',
      '--list-services',
      action='store_true',
      dest='list_services',
      help='List the name of each registered "chromite.api.Service/Method".')

  # Run configuration options.
  test_group = parser.add_argument_group(
      'Testing Options',
      'These options are used to execute various tests against the API. These '
      'options are mutually exclusive. Calling code can use these options to '
      'validate inputs and test their handling of each return code case for '
      'each endpoint.')
  call_modifications = test_group.add_mutually_exclusive_group()
  call_modifications.add_argument(
      '--validate-only',
      action='store_true',
      default=False,
      help='When set, only runs the argument validation logic. Calls produce '
           'a return code of 0 iff the input proto comprises arguments that '
           'are a valid call to the endpoint, or 1 otherwise.')
  # See: api/faux.py for the mock call and error implementations.
  call_modifications.add_argument(
      '--mock-call',
      action='store_true',
      default=False,
      help='When set, returns a valid, mock response rather than running the '
           'endpoint. This allows API consumers to more easily test their '
           'implementations against the version of the API being called. '
           'This argument will always result in a return code of 0.')
  call_modifications.add_argument(
      '--mock-error',
      action='store_true',
      default=False,
      help='When set, return a valid, mock error response rather than running '
           'the endpoint. This allows API consumers to test their error '
           'handling semantics against the version of the API being called. '
           'This argument will always result in a return code of 2 iff the '
           'endpoint ever produces a return code of 2, otherwise will always'
           'produce a return code of 1.')
  call_modifications.add_argument(
      '--mock-invalid',
      action='store_true',
      default=False,
      help='When set, return a mock validation error response rather than '
           'running the endpoint. This allows API consumers to test their '
           'validation error handling semantics against the version of the API '
           'being called without having to understand how to construct an '
           'invalid request. '
           'This argument will always result in a return code of 1.')

  return parser


def _ParseArgs(argv, router):
  """Parse and validate arguments."""
  parser = GetParser()
  opts = parser.parse_args(argv)

  methods = router.ListMethods()

  if opts.list_services:
    # We just need to print the methods and we're done.
    for method in methods:
      print(method)
    sys.exit(0)

  # Positional service_method argument validation.
  if not opts.service_method:
    parser.error('Must pass "Service/Method".')

  parts = opts.service_method.split('/')
  if len(parts) != 2:
    parser.error(
        'Must pass the correct format: (e.g. chromite.api.SdkService/Create).'
        'Use --list-methods to see a full list.')

  if opts.service_method not in methods:
    # Unknown method, try to match against known methods and make a suggestion.
    # This is just for developer sanity, e.g. misspellings when testing.
    matched = matching.GetMostLikelyMatchedObject(
        methods, opts.service_method, matched_score_threshold=0.6)
    error = 'Unrecognized service name.'
    if matched:
      error += '\nDid you mean: \n%s' % '\n'.join(matched)
    parser.error(error)

  opts.service = parts[0]
  opts.method = parts[1]

  # --input-json and --output-json validation.
  if not opts.input_json or not opts.output_json:
    parser.error('--input-json and --output-json are both required.')

  if not os.path.exists(opts.input_json):
    parser.error('Input file does not exist.')

  # Build the config object from the options.
  opts.config = api_config_lib.ApiConfig(
      validate_only=opts.validate_only,
      mock_call=opts.mock_call,
      mock_error=opts.mock_error)

  opts.Freeze()
  return opts


def main(argv):
  with cros_build_lib.ContextManagerStack() as stack:

    router = router_lib.GetRouter()
    opts = _ParseArgs(argv, router)

    if opts.tee_log:
      stack.Add(tee.Tee, opts.tee_log)
      logging.info('Teeing stdout and stderr to %s', opts.tee_log)

    if opts.mock_invalid:
      # --mock-invalid handling. We print error messages, but no output is ever
      # set for validation errors, so we can handle it by just giving back the
      # correct return code here.
      return controller.RETURN_CODE_INVALID_INPUT

    try:
      return router.Route(opts.service, opts.method, opts.input_json,
                          opts.output_json, opts.config)
    except router_lib.Error as e:
      # Handle router_lib.Error derivatives nicely, but let anything else bubble
      # up.
      cros_build_lib.Die(e)
