#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2017 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.
"""Generates markdown from the JSON schema."""

from __future__ import print_function

import argparse
import collections
import itertools
import os.path
import re
import sys

import yaml  # pylint: disable=import-error

import libcros_schema


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='Generates Markdown documentation based on the config schema')
  parser.add_argument(
      '-s',
      '--schema',
      default='cros_config_host/cros_config_schema.yaml',
      type=str,
      help='Schema file that is processed')
  parser.add_argument(
      '-o', '--output', type=str, help='Output file that will be generated')
  return parser.parse_args(argv)


def PopulateTypeDef(
    name,
    type_def,
    ref_types,
    output,
    inherited_build_only=False):
  """Populates type definitions in the output (recursive)

  Args:
    name: Name of the type
    type_def: Dict containing all of the type def attributes
    ref_types: Shared type definitions using the #ref attribute
    output: Running array of markdown string output lines
    inherited_build_only: Boolean, whether this element is the child of a
        build-only element.
  """
  child_types = collections.OrderedDict()
  output.append('### %s' % name)
  output.append('| Attribute | Type   | RegEx     | Required | Oneof Group '
                '| Build-only | Description |')
  output.append('| --------- | ------ | --------- | -------- | ----------- '
                '| ---------- | ----------- |')

  attrs_by_group = {'': collections.OrderedDict(
      sorted(type_def.get('properties', {}).items()))}
  group_index = 0
  for group in itertools.chain(type_def.get('oneOf', []),
                               type_def.get('anyOf', [])):
    group_attrs = collections.OrderedDict(
        sorted(group.get('properties', {}).items()))
    group_name = 'GROUP(%s)' % group_index
    for group_attr in group_attrs.values():
      match = re.match(r'\[(.*)\] .*', group_attr.get('description', ''))
      if match:
        group_name = match.group(1)
    attrs_by_group[group_name] = group_attrs
    group_index = group_index + 1

  additional_props = type_def.get('additionalProperties', False)
  if additional_props:
    output.append(
        '| [ANY] | N/A | N/A | N/A | N/A | N/A | '
        'This type allows additional properties not governed by the schema. '
        'See the type description for details on these additional properties.|')

  for attr_group_name, attrs in attrs_by_group.items():
    for attr in attrs:
      attr_name = attr

      # https://github.com/google/gitiles/blob/master/Documentation/markdown.md#named-anchors
      attr_anchor = ''
      for c in attr_name:
        if c.isalnum():
          attr_anchor += c
        elif c.isspace():
          attr_anchor += '-'
        else:
          attr_anchor += '_'
      attr_anchor = re.sub('-+', '-', attr_anchor)
      attr_anchor = re.sub('_+', '_', attr_anchor)

      type_attrs = attrs[attr]
      if '$ref' in type_attrs:
        type_attrs = ref_types[type_attrs['$ref']]

      attr_type = type_attrs['type']
      regex = type_attrs.get('pattern', '')
      if regex:
        # Regex need escaping for markdown
        regex = '```%s```' % regex
      description = type_attrs.get('description', '')
      description = description.replace('\n', ' ')
      required_list = type_def.get('required', [])
      required = attr in required_list
      build_only = (inherited_build_only
                    or type_attrs.get('build-only-element', False))
      if type_attrs['type'] == 'object':
        child_types[attr_name] = type_attrs
        if build_only:
          child_types[attr_name]['build-only-element'] = True
        attr_type = '[%s](#%s)' % (attr_name, attr_anchor)
      elif type_attrs['type'] == 'array':
        description = type_attrs['items'].get('description', '')
        if type_attrs['items']['type'] == 'object':
          child_types[attr_name] = type_attrs['items']
          if build_only:
            child_types[attr_name]['build-only-element'] = True
          attr_type = 'array - [%s](#%s)' % (attr_name, attr_anchor)
        else:
          attr_type = 'array - %s' % type_attrs['items']['type']
      elif type_attrs['type'] == 'integer':
        if 'minimum' in type_attrs:
          description += ' Minimum value: %s.' % hex(type_attrs['minimum'])
        if 'maximum' in type_attrs:
          description += ' Maximum value: %s.' % hex(type_attrs['maximum'])

      output_tuple = (attr_name,
                      attr_type,
                      regex,
                      required,
                      attr_group_name,
                      build_only,
                      description)
      output.append('| %s | %s | %s | %s | %s | %s | %s |' % output_tuple)

  output.append('')
  for child_type in child_types:
    child_is_build_only = (inherited_build_only
                           or child_types[child_type].get('build-only-element',
                                                          False))
    PopulateTypeDef(child_type, child_types[child_type], ref_types, output,
                    inherited_build_only=child_is_build_only)


def Main(schema, output):
  """Generates markdown documentation based on the JSON schema.

  Args:
    schema: Schema file.
    output: Output file.
  """
  schema_yaml = yaml.load(
      libcros_schema.ApplyImports(schema), Loader=yaml.SafeLoader)
  ref_types = {}
  for type_def in schema_yaml.get('typeDefs', []):
    ref_types['#/typeDefs/%s' % type_def] = schema_yaml['typeDefs'][type_def]

  type_def_outputs = []
  type_def_outputs.append('[](begin_definitions)')
  type_def_outputs.append('')
  PopulateTypeDef(
      'model',
      schema_yaml['properties']['chromeos']['properties']['configs']['items'],
      ref_types, type_def_outputs)
  type_def_outputs.append('')
  type_def_outputs.append('[](end_definitions)')
  type_def_outputs.append('')

  if output:
    pre_lines = []
    post_lines = []

    if os.path.isfile(output):
      with open(output) as output_stream:
        output_lines = output_stream.readlines()
        pre_section = True
        post_section = False
        for line in output_lines:
          if 'begin_definitions' in line:
            pre_section = False

          if pre_section:
            pre_lines.append(line)

          if post_section:
            post_lines.append(line)

          if 'end_definitions' in line:
            post_section = True

    with open(output, 'w') as output_stream:
      if pre_lines:
        output_stream.writelines(pre_lines)

      output_stream.write('\n'.join(type_def_outputs))

      if post_lines:
        output_stream.writelines(post_lines)
  else:
    print('\n'.join(type_def_outputs))


if __name__ == '__main__':
  args = ParseArgs(sys.argv[1:])
  Main(args.schema, args.output)
