# 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 GetScriptName():
  return os.path.basename(os.path.abspath(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(lines):
  package_re = re.compile(r'^package (.*);')
  class_re = re.compile(r'.*class (.*) {')
  package = ''
  class_name = ''
  for line in lines:
    package_line = package_re.match(line)
    if package_line:
      package = package_line.groups()[0]
    class_line = class_re.match(line)
    if class_line:
      class_name = class_line.groups()[0]
      break
  return package, class_name


# TODO(crbug.com/937282): 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 __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 _ExtractVariable(self, line):
    match = StringFileParser.STRING_RE.match(line)
    return match.group(1) if match else None

  def _ExtractValue(self, line):
    match = StringFileParser.VALUE_RE.search(line)
    return match.group(1) if match else None

  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()
    else:
      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
