# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import os
import re
import sys


def CreateDefaultTemplate(java_class, placeholder):
  assert '.' in java_class, 'Wanted fully-qualified name. Found ' + java_class
  package, _, class_name = java_class.rpartition('.')

  script_name = GetScriptName()
  return f"""\
// Generated by {script_name}

package {package};

public final class {class_name} {{
    private {class_name}() {{}}

{placeholder}
}}
"""


def GetScriptName():
  return os.path.basename(sys.argv[0])


def GetJavaFilePath(java_package, class_name):
  package_path = java_package.replace('.', os.path.sep)
  file_name = class_name + '.java'
  return os.path.join(package_path, file_name)


def KCamelToShouty(s):
  """Convert |s| from kCamelCase or CamelCase to SHOUTY_CASE.

  kFooBar -> FOO_BAR
  FooBar -> FOO_BAR
  FooBAR9 -> FOO_BAR9
  FooBARBaz -> FOO_BAR_BAZ
  """
  if not re.match(r'^k?([A-Z][^A-Z]+|[A-Z0-9]+)+$', s):
    return s
  # Strip the leading k.
  s = re.sub(r'^k', '', s)
  # Treat "WebView" like one word.
  s = re.sub(r'WebView', r'Webview', s)
  # Add _ between title words and anything else.
  s = re.sub(r'([^_])([A-Z][^A-Z_0-9]+)', r'\1_\2', s)
  # Add _ between lower -> upper transitions.
  s = re.sub(r'([^A-Z_0-9])([A-Z])', r'\1_\2', s)
  return s.upper()


class JavaString:
  def __init__(self, name, value, comments):
    self.name = KCamelToShouty(name)
    self.value = value
    self.comments = '\n'.join('    ' + x for x in comments)

  def Format(self):
    return '%s\n    public static final String %s = %s;' % (
        self.comments, self.name, self.value)


def ParseTemplateFile(data):
  if m := re.search(r'^package (.*);[\s\S]+\bclass (\w+) {',
                    data,
                    flags=re.MULTILINE):
    package, class_name = m.groups()
    return package, class_name
  raise Exception('Could not find java package.')


# TODO(crbug.com/40616187): Work will be needed if we want to annotate specific
# constants in the file to be parsed.
class CppConstantParser:
  """Parses C++ constants, retaining their comments.

  The Delegate subclass is responsible for matching and extracting the
  constant's variable name and value, as well as generating an object to
  represent the Java representation of this value.
  """
  SINGLE_LINE_COMMENT_RE = re.compile(r'\s*(// [^\n]*)')

  class Delegate:
    def ExtractConstantName(self, line):
      """Extracts a constant's name from line or None if not a match."""
      raise NotImplementedError()

    def ExtractValue(self, line):
      """Extracts a constant's value from line or None if not a match."""
      raise NotImplementedError()

    def CreateJavaConstant(self, name, value, comments):
      """Creates an object representing the Java analog of a C++ constant.

      CppConstantParser will not interact with the object created by this
      method. Instead, it will store this value in a list and return a list of
      all objects from the Parse() method. In this way, the caller may define
      whatever class suits their need.

      Args:
        name: the constant's variable name, as extracted by
          ExtractConstantName()
        value: the constant's value, as extracted by ExtractValue()
        comments: the code comments describing this constant
      """
      raise NotImplementedError()

    def RequiresMultilineValueParsing(self):
      """Whether the parser should look for values across multiple lines."""
      return False

  def __init__(self, delegate, lines):
    self._delegate = delegate
    self._lines = lines
    self._in_variable = False
    self._in_comment = False
    self._package = ''
    self._current_comments = []
    self._current_name = ''
    self._current_value = ''
    self._constants = []

  def _Reset(self):
    self._current_comments = []
    self._current_name = ''
    self._current_value = ''
    self._in_variable = False
    self._in_comment = False

  def _AppendConstant(self):
    self._constants.append(
        self._delegate.CreateJavaConstant(self._current_name,
                                          self._current_value,
                                          self._current_comments))
    self._Reset()

  def _ParseValue(self, line):
    current_value = self._delegate.ExtractValue(line)
    if current_value is not None:
      self._current_value = current_value
      self._AppendConstant()
    elif not self._delegate.RequiresMultilineValueParsing():
      self._Reset()

  def _ParseComment(self, line):
    comment_line = CppConstantParser.SINGLE_LINE_COMMENT_RE.match(line)
    if comment_line:
      self._current_comments.append(comment_line.groups()[0])
      self._in_comment = True
      self._in_variable = True
      return True
    self._in_comment = False
    return False

  def _ParseVariable(self, line):
    current_name = self._delegate.ExtractConstantName(line)
    if current_name is not None:
      self._current_name = current_name
      current_value = self._delegate.ExtractValue(line)
      if current_value is not None:
        self._current_value = current_value
        self._AppendConstant()
      else:
        self._in_variable = True
      return True
    self._in_variable = False
    return False

  def _ParseLine(self, line):
    if not self._in_variable:
      if not self._ParseVariable(line):
        self._ParseComment(line)
      return

    if self._in_comment:
      if self._ParseComment(line):
        return
      if not self._ParseVariable(line):
        self._Reset()
      return

    if self._in_variable:
      self._ParseValue(line)

  def Parse(self):
    """Returns a list of objects representing C++ constants.

    Each object in the list was created by Delegate.CreateJavaValue().
    """
    for line in self._lines:
      self._ParseLine(line)
    return self._constants
