#!/usr/bin/env python3
# Copyright 2012 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Format for the JSON schema file:
# {
#   "type_name": "DesiredCStructName",
#   "system-headers": [   // Optional list of system headers to be included by
#     "header"            // the .h.
#   ],
#   "headers": [          // Optional list of headers to be included by the .h.
#     "path/to/header.h"
#   ],
#   "schema": [           // Fields of the generated structure.
#     {
#       "field": "my_enum_field",
#       "type": "enum",   // Either: int, string, string16, enum, array, struct.
#       "default": "RED", // Optional. Cannot be used for array.
#       "ctype": "Color"  // Only for enum, specify the C type.
#     },
#     {
#       "field": "my_int_array_field",  // my_int_array_field_size will also
#       "type": "array",                // be generated.
#       "contents": {
#         "type": "int"   // Either: int, string, string16, enum, array.
#       }
#     },
#     {
#       "field": "my_struct_field",
#       "type_name": "PointStuct",
#       "type": "struct",
#       "fields": [
#         {"field": "x", "type": "int"},
#         {"field": "y", "type": "int"}
#       ]
#     },
#     ...
#   ]
# }
#
# Format for the JSON description file:
# {
#   "int_variables": {    // An optional list of constant int variables.
#     "kDesiredConstantName": 45
#   },
#   "elements": {         // All the elements for which to create static
#                         // initialization code in the .cc file.
#     "my_const_variable": {
#       "my_int_field": 10,
#       "my_string_field": "foo bar",
#       "my_enum_field": "BLACK",
#       "my_int_array_field": [ 1, 2, 3, 5, 7 ],
#       "my_struct_field": {"x": 1, "y": 2}
#     },
#     "my_other_const_variable": {
#       ...
#     }
#   }
# }

from datetime import datetime
import io
import json
import optparse
import os.path
import re
import sys

_script_path = os.path.realpath(__file__)

sys.path.insert(0, os.path.normpath(_script_path + "/../../json_comment_eater"))
try:
  import json_comment_eater
finally:
  sys.path.pop(0)

from aggregation import AggregationKind
from aggregation import GenerateCCAggregation
from aggregation import GenerateHHAggregation
from aggregation import GetAggregationDetails
import class_generator
import element_generator
import java_element_generator
import struct_generator


HEAD = u"""// Copyright %d The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// GENERATED FROM THE SCHEMA DEFINITION AND DESCRIPTION IN
//   %s
//   %s
// using json_to_struct.py. DO NOT EDIT.

"""


def _GenerateHeaderGuard(h_filename):
  """Generates the string used in #ifndef guarding the header file.
  """
  result = re.sub(u'[%s\\\\.]' % os.sep, u'_', h_filename.upper())
  return re.sub(u'^_*', '', result) + u'_'  # Remove leading underscores.


def _GenerateH(basepath, fileroot, head, namespace, schema, description):
  """Generates the .h file containing the definition of the structure specified
  by the schema.

  Args:
    basepath: The base directory in which files are generated.
    fileroot: The filename and path, relative to basepath, of the file to
        create, without an extension.
    head: The string to output as the header of the .h file.
    namespace: A string corresponding to the C++ namespace to use.
    schema: A dict containing the schema. See comment at the top of this file.
    description: A dict containing the description. See comment at the top of
        this file.
  """

  h_filename = fileroot + u'.h'
  with io.open(os.path.join(basepath, h_filename), 'w', encoding='utf-8') as f:
    f.write(head)

    header_guard = _GenerateHeaderGuard(h_filename)
    f.write(u'#ifndef %s\n' % header_guard)
    f.write(u'#define %s\n' % header_guard)
    f.write(u'\n')

    aggregation = GetAggregationDetails(description)

    if aggregation.kind == AggregationKind.ARRAY:
      f.write("#include <array>\n")
    f.write(u'#include <cstddef>\n')
    f.write(u'\n')

    if system_headers := schema.get(u'system-headers', []):
      for header in system_headers:
        f.write(u'#include <%s>\n' % header)
      f.write(u'\n')

    headers = schema.get(u'headers', [])
    if aggregation.kind == AggregationKind.MAP:
      headers.append("base/containers/fixed_flat_map.h")

    for header in sorted(set(headers)):
      f.write(u'#include "%s"\n' % header)
    f.write(u'\n')

    if namespace:
      f.write(u'namespace %s {\n' % namespace)
      f.write(u'\n')

    f.write(struct_generator.GenerateStruct(
      schema['type_name'], schema['schema']))
    f.write(u'\n')

    for var_name, value in description.get('int_variables', {}).items():
      f.write(u'extern const int %s;\n' % var_name)

    # Generate forward declarations of all elements.
    if aggregation.export_items:
      f.write(u'\n')
      for element_name, element in description['elements'].items():
        f.write(u'extern const %s %s;\n' % (schema['type_name'], element_name))

    aggregated = GenerateHHAggregation(schema['type_name'], aggregation)
    if aggregated:
      f.write(aggregated)

    if namespace:
      f.write(u'\n')
      f.write(u'}  // namespace %s\n' % namespace)

    f.write(u'\n')
    f.write(u'#endif  // %s\n' % header_guard)


def _GenerateCC(basepath, fileroot, head, namespace, schema, description):
  """Generates the .cc file containing the static initializers for the
  of the elements specified in the description.

  Args:
    basepath: The base directory in which files are generated.
    fileroot: The filename and path, relative to basepath, of the file to
        create, without an extension.
    head: The string to output as the header of the .cc file.
    namespace: A string corresponding to the C++ namespace to use.
    schema: A dict containing the schema. See comment at the top of this file.
    description: A dict containing the description. See comment at the top of
        this file.
  """

  with io.open(os.path.join(basepath, fileroot + '.cc'), 'w',
               encoding='utf-8') as f:
    f.write(head)

    f.write('#include "%s"\n' % (fileroot + u'.h'))
    f.write('\n')

    if namespace:
      f.write('namespace %s {\n' % namespace)
      f.write('\n')

    aggregation = GetAggregationDetails(description)

    if not aggregation.export_items:
      f.write('namespace {\n')
      f.write('\n')

    f.write(element_generator.GenerateElements(schema['type_name'],
        schema['schema'], description))

    if not aggregation.export_items:
      f.write('\n}  // anonymous namespace \n\n')

    aggregated = GenerateCCAggregation(schema['type_name'], aggregation)
    if aggregated:
      f.write(aggregated)

    if namespace:
      f.write(u'\n')
      f.write(u'}  // namespace %s\n' % namespace)


def _GenerateJava(basepath, fileroot, head, package, schema, description):
  """Generates the .java file containing the static initializers for the
  of the elements specified in the description.

  Args:
    basepath: The base directory in which files are generated.
    fileroot: The filename and path, relative to basepath, of the file to
        create, without an extension.
    head: The string to output as the header of the .cc file.
    package: A string corresponding to the Java package to use.
    schema: A dict containing the schema. See comment at the top of this file.
    description: A dict containing the description. See comment at the top of
        this file.
  """
  with io.open(os.path.join(basepath, fileroot + '.java'),
               'w',
               encoding='utf-8') as f:
    f.write(head)

    if package:
      f.write(u'package %s;\n' % package)
      f.write(u'\n')

    f.write(u'public class GeneratedFieldtrialTestingConfigVariations {\n')

    f.write(
        class_generator.GenerateInnerClasses(schema['type_name'],
                                             schema['schema']))

    f.write(
        java_element_generator.GenerateElements(schema['type_name'],
                                                schema['schema'], description))

    f.write(u'} // class GeneratedFieldtrialTestingConfigVariations\n')


def _Load(filename):
  """Loads a JSON file int a Python object and return this object.
  """
  # TODO(beaudoin): When moving to Python 2.7 use object_pairs_hook=OrderedDict.
  with io.open(filename, 'r', encoding='utf-8') as handle:
    result = json.loads(json_comment_eater.Nom(handle.read()))
  return result


def GenerateClass(basepath,
                  output_root,
                  package,
                  schema,
                  description,
                  description_filename,
                  schema_filename,
                  year=None):
  """Generates a Java class from a JSON description.

  Args:
    basepath: The base directory in which files are generated.
    output_root: The filename and path, relative to basepath, of the file to
        create, without an extension.
    package: A string corresponding to the Java package to use.
    schema: A dict containing the schema. See comment at the top of this file.
    description: A dict containing the description. See comment at the top of
        this file.
    description_filename: The description filename. This is added to the
        header of the outputted files.
    schema_filename: The schema filename. This is added to the header of the
        outputted files.
    year: Year to display next to the copy-right in the header.
  """
  year = int(year) if year else datetime.now().year
  head = HEAD % (year, schema_filename, description_filename)
  _GenerateJava(basepath, output_root, head, package, schema, description)


def GenerateStruct(basepath, output_root, namespace, schema, description,
                   description_filename, schema_filename, year=None):
  """Generates a C++ struct from a JSON description.

  Args:
    basepath: The base directory in which files are generated.
    output_root: The filename and path, relative to basepath, of the file to
        create, without an extension.
    namespace: A string corresponding to the C++ namespace to use.
    schema: A dict containing the schema. See comment at the top of this file.
    description: A dict containing the description. See comment at the top of
        this file.
    description_filename: The description filename. This is added to the
        header of the outputted files.
    schema_filename: The schema filename. This is added to the header of the
        outputted files.
    year: Year to display next to the copy-right in the header.
  """
  year = int(year) if year else datetime.now().year
  head = HEAD % (year, schema_filename, description_filename)
  _GenerateH(basepath, output_root, head, namespace, schema, description)
  _GenerateCC(basepath, output_root, head, namespace, schema, description)

if __name__ == '__main__':
  parser = optparse.OptionParser(
      description='Generates an C++ array of struct from a JSON description.',
      usage='usage: %prog [option] -s schema description')
  parser.add_option('-b', '--destbase',
      help='base directory of generated files.')
  parser.add_option('-d', '--destdir',
      help='directory to output generated files, relative to destbase.')
  parser.add_option('-n', '--namespace',
      help='C++ namespace for generated files. e.g search_providers.')
  parser.add_option('-s', '--schema', help='path to the schema file, '
      'mandatory.')
  parser.add_option('-o', '--output', help='output filename, ')
  (opts, args) = parser.parse_args()

  if not opts.schema:
    parser.error('You must specify a --schema.')

  description_filename = os.path.normpath(args[0])
  root, ext = os.path.splitext(description_filename)
  shortroot = opts.output if opts.output else os.path.split(root)[1]
  if opts.destdir:
    output_root = os.path.join(os.path.normpath(opts.destdir), shortroot)
  else:
    output_root = shortroot

  if opts.destbase:
    basepath = os.path.normpath(opts.destbase)
  else:
    basepath = ''

  schema = _Load(opts.schema)
  description = _Load(description_filename)
  GenerateStruct(basepath, output_root, opts.namespace, schema, description,
                 description_filename, opts.schema)
