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

"""Transforms and validates cros config test from source YAML to target JSON"""

from __future__ import print_function

import argparse
import json
import os
import sys

import yaml  # pylint: disable=import-error

# pylint: disable=wrong-import-position
this_dir = os.path.dirname(__file__)
sys.path.insert(0, this_dir)
import libcros_schema
sys.path.pop(0)

default_test_schema = os.path.join(this_dir, 'cros_config_test_schema.yaml')

CHROMEOS = 'chromeos'
DEVICES = 'devices'
ROOT_PATH = 'properties/chromeos/properties/devices/items/properties'


def ParseArgs(argv):
  """Parse the available arguments.

  Invalid arguments or -h cause this function to print a message and exit.

  Args:
    argv: List of string arguments (excluding program name / argv[0])

  Returns:
    argparse.Namespace object containing the attributes.
  """
  parser = argparse.ArgumentParser(description=__doc__)
  parser.add_argument(
      '-s',
      '--schema',
      type=str,
      help='Path to the schema file used to validate the config')
  parser.add_argument(
      '-c',
      '--config',
      type=str,
      help='Path to the YAML config file that will be validated/transformed',
      required=True)
  parser.add_argument(
      '-f',
      '--filter',
      type=str,
      help='Filter device by name')
  parser.add_argument(
      '-o',
      '--output',
      type=str,
      help='Output file that will be generated by the transform (system file)',
      required=True)
  return parser.parse_args(argv)


def TransformConfig(config, device_filter=None):
  """Transforms the source config (YAML) to the target system format (JSON)

  Applies consistent transforms to covert a source YAML configuration into
  JSON output that will be used by the tast test program.

  Args:
    config: Config that will be transformed.
    device_filter: Only returns configs that match the filter.

  Returns:
    Resulting JSON output from the transform.
  """
  config_yaml = yaml.load(config, Loader=yaml.SafeLoader)
  json_from_yaml = json.dumps(config_yaml, sort_keys=True, indent=2)
  json_config = json.loads(json_from_yaml)
  configs = []
  if DEVICES in json_config[CHROMEOS]:
    for device in json_config[CHROMEOS][DEVICES]:
      configs.append(device)

  if device_filter:
    configs = [
        config for config in configs if device_filter == config['device-name']
    ]

  # Drop everything except for devices since they were just used as shared
  # config in the source yaml.
  json_config = {
      CHROMEOS: {
          DEVICES: configs,
      },
  }

  return libcros_schema.FormatJson(json_config)


def MergeConfig(yaml_file, filter_name):
  """Evaluates and merges all config files into a single configuration.

  Args:
    yaml_file: List of source config files that will be transformed/merged.
    filter_name: Name of device to filter on.

  Returns:
    Final merged JSON result.
  """
  yaml_with_imports = libcros_schema.ApplyImports(yaml_file)
  json_transformed_file = TransformConfig(yaml_with_imports, filter_name)
  return json_transformed_file


def Start(config, filter_name, output, schema):
  """Transforms and validates a cros config test file for use on the system

  Applies consistent transforms to covert a source YAML configuration into
  a JSON file that will be used on the system by cros_config tast tests.

  Verifies that the file complies with the schema verification rules and
  performs additional verification checks for config consistency.

  Args:
    config: Source config file that will be transformed/verified.
    filter_name: Device name to filter on.
    output: Output file that will be generated by the transform.
    schema: Schema file used to verify the config.
  """
  json_transform = MergeConfig(config, filter_name)

  if schema is None:
    schema = default_test_schema
  with open(schema, 'r') as schema_stream:
    libcros_schema.ValidateConfigSchema(
        schema_stream.read(), libcros_schema.FormatJson(json_transform))

  if output:
    with open(output, 'w') as output_stream:
      # Using print function adds proper trailing newline.
      print(json_transform, file=output_stream)
  else:
    print(json_transform)


# The distutils generated command line wrappers will not pass us argv.
def main(argv=None):
  """Main program which parses sys.argv and runs

  Args:
    argv: List of command line arguments, if None uses sys.argv.
  """
  if argv is None:
    argv = sys.argv[1:]
  opts = ParseArgs(argv)
  Start(opts.config, opts.filter, opts.output, opts.schema)


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
