#!/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/HEAD/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)
