#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2019 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.
"""Generate the overalls class and mock."""
from __future__ import print_function

import argparse
import datetime
import os
import re
import subprocess
import sys

_LICENSE_STRING = """
// Copyright %d 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.
""".strip() % datetime.datetime.now().year

_OVERALLS_CLASS_DESCRIPTION = (
    '// |Overalls| wraps trousers API (including Tspi and Trspi family), with '
    'the wrapper API name being the trousers API names of which the first "T" '
    'replaced by "O". For example, |Overalls::Ospi_Context_Create| calls '
    '|Tspi_Context_Create|.\n//\n// The purpose of this wrapper class is to '
    'make trousers APIs to be mock-able so we can enable the callers of '
    'trouser to be unittested in googletest framework.')


def _get_repo_related_path(path):
  """Replaces the path before 'src/platform2' by '//'."""
  path = os.path.realpath(path)
  token = 'src/platform2'
  return '//' + token + path.split(token, 1)[1]


_THIS_FILE_PATH = _get_repo_related_path(__file__)
_THIS_FILE_DIR = os.path.dirname(os.path.realpath(__file__))
_PLATFORM2_DIR = _THIS_FILE_DIR.rsplit('libhwsec', 1)[0]
_TROUSERS_INCLUDE_DIR = _PLATFORM2_DIR.rsplit(
    'platform2', 1)[0] + 'third_party/trousers/src/include'
_OUTPUT_SUBDIR = 'libhwsec/overalls'

_GENERATOR_INFO = """
// This file is GENERATED and do not modify it manually.
// To reproduce the generation process, run %s with arguments as:
// %s
""".strip() % (_THIS_FILE_PATH, ' '.join(sys.argv[1:]))


def build_filter(wd):
  """Builds a filter function based on used |trousers| APIs in under |wd|.

  Given the path |wd|, this function find out all the usage of |trousers| APIs
  using |git grep|. The content of |overalls| project itself is ignored.

  Args:
    wd: String of the woring directory where |git grep| is run.

  Returns:
    A filter function that returns |True| iff the usage is found by |git grep|.
  """
  cmd = [
      'git', 'grep', '-oh', '-E', r'\bTr?spi_([a-zA-Z0-9]+_)?[a-zA-Z0-9]+\b',
      ':(exclude)libhwsec/overalls/*'
  ]
  all_usages = subprocess.check_output(cmd, cwd=wd).decode('utf-8')
  all_usages = set(all_usages.splitlines())
  return lambda x: x in all_usages


def parse_trousers_input_args(s):
  """Parses Trspi family's input arguments.

  Given a string from of input arguments of a trousers API, the input arguments
  parsed into tokens and then convert to tuples. For example:
  "BYTE *s, unsigned *len"
  ->
  [("BYTE *", "s"), ("unsigned *", "len")]

  Args:
    s: String representation of the input arguments of a certain Trspi function.

  Returns:
    A list of tuples in form of (data type, variable name).
  """
  arr = s.split(',')
  for i, p in enumerate(arr):
    p = p.strip()
    # are stick with the variable name, e.g., UINT64 *offset, so the separator
    # could be last ' ' or '*'.
    pos = p.strip().rfind('*')
    if pos == -1:
      pos = p.rfind(' ')
      if pos == -1:
        pos = len(p)
    var_type, var_name = p[:pos + 1].strip(), p[pos + 1:].strip()
    arr[i] = (var_type, var_name)
  return arr


def process_function_macro(args1, args2, arr2):
  """Parses Trspi family's input arguments for those implemented by macros.

  Args:
    args1: String representation of the input arguments of a certain the
      function as the caller.
    args2: String representation of the input arguments of a certain the
      function as the callee.
    arr2: List returned by |parse_trousers_input_args| when processing the
      callee.

  Returns:
    A list of tuples in form of (type, name).
  """
  tokens1 = args1.replace(' ', '').split(',')
  tokens2 = args2.replace(' ', '').split(',')
  return [arr2[tokens2.index(x)] for x in tokens1]


def process_trousers_h(input_string):
  """Processes the file content of trousers.h

  Parses the input file content and tokenize each function declaration into a
  3-tuple as shown in the following example:

  ***declaration***:
  BYTE *Trspi_Native_To_UNICODE(BYTE *string, unsigned *len);

  ***output***:
  ("BYTE *", "Trspi_Native_To_UNICODE",
  [("BYTE *", "s"), ("unsigned *", "len")])

  Note: the macro-style implementaions is also parsed into the same form.

  Args:
    input_string: the file content of trousers.h in a string.

  Returns:
    A list of 3-tuples where the data is in order of return type, function name,
    and a list of 2-tuple in form of (data type, variable name)
  """
  input_string = input_string.replace('\\\n', '').replace(',\n', ', ')
  r = re.compile(r'(void|TSS_RESULT|BYTE|char|UINT32|int)'
                 r'([\s\*]+)Trspi_([\w\d_]+)\((.*)\);')
  arr = []
  table = {}
  for m in r.finditer(input_string):
    return_type = (m.group(1) + m.group(2)).strip()
    name = 'Trspi_' + m.group(3)
    arguments = parse_trousers_input_args(m.group(4))
    arr.append((return_type, name, arguments))
    table[name] = arr[-1]
  # Processes the macros.
  r = re.compile(
      r'#define\s+Trspi_([\w\d_]+)\((.*)\)\s+Trspi_([\w\d_]+)\((.*)\)')

  for m in r.finditer(input_string):
    name = 'Trspi_' + m.group(1)
    callee = table['Trspi_' + m.group(3)]
    return_type = callee[0]
    arguments = process_function_macro(m.group(2), m.group(4), callee[2])
    arr.append((return_type, name, arguments))

  # For self-test purpose.
  expected_api_counts = sum(
      1 for x in input_string.splitlines() if ' Trspi_' in x or ' *Trspi_' in x)
  # Offset by 1 because there is also a strcut declaration starting from
  # "Trspi_". The offset should be adjusted accordingly if trousers.h changes.
  assert expected_api_counts == len(arr) + 1

  return arr


def process_tspi_h(input_string):
  """Process the file content of tspi.h

  Parses the input file content and tokenize each function declaration into a
  3-tuple as shown in the following example:

  ***declaration***:
  TSPICALL Tspi_Context_Create
  (
      TSS_HCONTEXT*       phContext                      // out
  );

  ***output***:
  ("TSS_RESULT", "Tspi_Context_Create", [("TSS_HCONTEXT*", "phContext")])

  Args:
    input_string: the file content of tspi.h in a string.

  Returns:
    A list of 3-tuples of return type, function name, a list of 2-tuple in form
    of (data type, variable name)
  """
  r = re.compile(r'^TSPICALL[\s\S]*?;', flags=re.M)
  arr = []
  for m in r.finditer(input_string):
    tokens = m.group(0).splitlines()
    name = tokens[0].split()[1]
    arguments = []
    for t in tokens[2:-1]:
      var_type, var_name = t.split()[:2]
      arguments.append((var_type, var_name.replace(',', '')))
    arr.append(('TSS_RESULT', name, arguments))

  # For self-test purpose.
  expected_api_counts = input_string.count('\nTSPICALL')
  assert expected_api_counts == len(arr)

  return arr


def tuples_to_wrapper_class(wrapper_class_name, functions):
  """Generates a wrapper class as a string from the parsed result of headers."""

  def to_virtual_member_function(return_type, name, arguments):
    """Generates the function declaraion from a parsed API information."""
    for i, a in enumerate(arguments):
      if not a[1]:
        arguments[i] = (a[0], 'arg%d' % i)
    arguments_string = ','.join([' '.join(x) for x in arguments])
    inputs_string = ','.join([x[1] for x in arguments])
    caller_name = 'O' + name[1:]
    callee_name = name
    return 'virtual %s %s(%s){ return %s(%s); }' % (
        return_type, caller_name, arguments_string, callee_name, inputs_string)

  member_functions = '\n'.join(
      to_virtual_member_function(*x) for x in functions)
  ctor_and_dtor = '%s() = default;virtual ~%s() = default;' % (
      wrapper_class_name, wrapper_class_name)
  return '%s\nclass %s {\npublic:\n%s\n%s\n};\n' % (
      _OVERALLS_CLASS_DESCRIPTION, wrapper_class_name, ctor_and_dtor,
      member_functions)


def tuples_to_mock_class(wrapper_class_name, functions):
  """Generates a mock class as a string from the parsed result of headers."""

  def to_mock_method(return_type, name, arguments):
    """Generates the mock method from a parsed API information."""
    arguments_string = ','.join([' '.join(x) for x in arguments])
    arguments_string = ','.join([x[0] for x in arguments])
    # Falls back to CHECK(false) when too many arguments.
    if len(arguments) > 10:
      return ('%s %s(%s) override {CHECK(false) <<"too many arguments to be '
              'mockable.";return 0;}') % (return_type, name, arguments_string)
    return 'MOCK_METHOD%d(%s,%s(%s));' % (len(arguments), name, return_type,
                                          arguments_string)

  mock_methods = '\n'.join(to_mock_method(*x) for x in functions)

  mock_class_name = 'Mock' + wrapper_class_name
  ctor_and_dtor = '%s() = default;~%s() override = default;' % (mock_class_name,
                                                                mock_class_name)
  return 'class %s:public %s {\npublic:\n%s\n%s\n};\n' % (
      mock_class_name, wrapper_class_name, ctor_and_dtor, mock_methods)


def generate_source_code_string(include_guard, includes, namespaces, body):
  """Composes the inputs to a source file content.

  Args:
    include_guard: The string used as one-time includ guard.
    includes: The string of '#include ...' fields.
    namespaces: A iterable object that contains a series of namespaces.
    body: source code that put inside the nested namespaces depecified in the
      last argument.

  Returns:
    The file content string that is composed of the input parameters.
  """
  include_guard_begin = ''
  if include_guard:
    include_guard_begin = '#ifndef %s\n#define %s' % (include_guard,
                                                      include_guard)
  namespaces_begin = '\n'.join('namespace %s {' % x for x in namespaces)
  include_guard_end = ''
  if include_guard:
    include_guard_end = '#endif  // %s' % (include_guard)
  namespaces_end = '\n'.join('}  // namespace ' + x for x in namespaces)
  strings = (_LICENSE_STRING, _GENERATOR_INFO, include_guard_begin, includes,
             namespaces_begin, body, namespaces_end, include_guard_end)
  s = '\n\n'.join(strings)
  return s + '\n'


def generate_source_code_file(file_path, include_guard, includes, namespaces,
                              body):
  """Call |generate_source_code_string| and write the content to a file."""
  content = generate_source_code_string(include_guard, includes, namespaces,
                                        body)
  with open(file_path, 'w') as f:
    f.write(content)
  cmd = ['clang-format', '-sort-includes=0', '-i', file_path]
  subprocess.check_call(cmd)


def generate_include_guard(subdir, filename):
  """Generates the include guard for a C++ header.

  Args:
    subdir: the directory whare we put the generated file; it's relavtie to
      |platform2| repository.
    filename: the name of the file

  Returns:
    The macro used as the include guard.
  """
  subdir = subdir.strip('/\\')
  s = subdir.strip('/') + '_' + filename + '_'
  return s.replace('/', '_').replace('.', '_').upper()


def gen_arg_parser():
  """Creates the argument parser for the command line argument."""
  parser = argparse.ArgumentParser(description=__doc__)
  parser.add_argument(
      '--filter-by-usage',
      action='store_true',
      help='if set, crawl the entire platform2 repo and '
      'generate code corrsponding to only used funtions.')
  parser.add_argument(
      '--include-dir',
      type=str,
      default=_TROUSERS_INCLUDE_DIR,
      help='the directory containing trousers/trousers.h and tss/tspi.h. '
      'If not specified, the program locates '
      '"//src/third_party/trousers/src/include" in the same source tree of '
      'this python script.')
  parser.add_argument(
      '--subdir',
      type=str,
      default=_OUTPUT_SUBDIR,
      help='the output directory relative to //src/platform2 where the '
      'generated headers are placed (in order to generate include guard).'
      'If not specified, the sub-directory is "%s"' % _OUTPUT_SUBDIR)
  parser.add_argument(
      '--output-dir',
      type=str,
      default=_THIS_FILE_DIR,
      help='the output directory of the generated files. '
      'If not specified, it is the same directory as this python script.')
  return parser


def main(args):
  """The main function."""
  parser = gen_arg_parser()
  opts = parser.parse_args(args)

  trousers_dir = os.path.join(os.path.abspath(opts.include_dir), 'trousers')
  trousers_h_path = os.path.join(trousers_dir, 'trousers.h')
  with open(trousers_h_path, 'r') as f:
    input_string = f.read()
  result = process_trousers_h(input_string)
  tss_dir = os.path.join(os.path.abspath(opts.include_dir), 'tss')
  tss_h_path = os.path.join(tss_dir, 'tspi.h')
  with open(tss_h_path, 'r') as f:
    input_string = f.read()
  result += process_tspi_h(input_string)

  if opts.filter_by_usage:
    print('filtering by usage...')
    func = build_filter(_PLATFORM2_DIR)
    old_size = len(result)
    result = [x for x in result if func(x[1])]
    new_size = len(result)
    print('pruning %d out of %d APIs and new result has %d APIs' %
          (old_size - new_size, old_size, new_size))

  include_guard = generate_include_guard(opts.subdir, 'overalls.h')
  includes = ('#include <trousers/tss.h>\n#include <trousers/trousers.h> // '
              'NOLINT(build/include_alpha) - needs tss.h')
  namespaces = ('hwsec', 'overalls')
  file_path = os.path.join(opts.output_dir, 'overalls.h')
  generate_source_code_file(file_path, include_guard, includes, namespaces,
                            tuples_to_wrapper_class('Overalls', result))

  include_guard = generate_include_guard(opts.subdir, 'mock_overalls.h')
  includes = ('#include <base/logging.h>\n#include <gmock/gmock.h>\n#include '
              '"libhwsec/overalls/overalls.h"')
  namespaces = ('hwsec', 'overalls')
  file_path = os.path.join(opts.output_dir, 'mock_overalls.h')
  generate_source_code_file(
      file_path, include_guard, includes, namespaces,
      tuples_to_mock_class('Overalls',
                           [(x[0], 'O' + x[1][1:], x[2]) for x in result]))


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