# 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.

"""Utilies and constants specific to Chromium C++ code.
"""

from code import Code
from datetime import datetime
from model import PropertyType
import os
import posixpath
import re

CHROMIUM_LICENSE = (
"""// 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.""" % datetime.now().year
)
GENERATED_FILE_MESSAGE = """// GENERATED FROM THE API DEFINITION IN
//   %s
// by tools/json_schema_compiler.
// DO NOT EDIT.
"""
GENERATED_BUNDLE_FILE_MESSAGE = """// GENERATED FROM THE API DEFINITIONS IN
//   %s
// by tools/json_schema_compiler.
// DO NOT EDIT.
"""
GENERATED_FEATURE_MESSAGE = """// GENERATED FROM THE FEATURE DEFINITIONS IN
//   %s
// by tools/json_schema_compiler.
// DO NOT EDIT.
"""

def Classname(s):
  """Translates a namespace name or function name into something more
  suited to C++.

  eg experimental.downloads -> Experimental_Downloads
  updateAll -> UpdateAll
  update_all -> UpdateAll
  """
  if s == '':
    return 'EMPTY_STRING'

  if IsUnixName(s):
    result = CamelCase(s)
  else:
    result = '_'.join([x[0].upper() + x[1:] for x in re.split(r'\W', s)])

  # Ensure the class name follows c++ identifier rules by prepending an
  # underscore if needed.
  assert result
  if result[0].isdigit():
    result = '_' + result
  return result

def GetAsFundamentalValue(type_, src):
  """Returns the C++ code for retrieving a fundamental type from a
  Value into a variable.

  src: Value
  """
  if type_.property_type == PropertyType.BOOLEAN:
    s = '%s.GetIfBool()'
  elif type_.property_type == PropertyType.DOUBLE:
    s = '%s.GetIfDouble()'
  elif type_.property_type == PropertyType.INTEGER:
    s = '%s.GetIfInt()'
  elif (type_.property_type == PropertyType.STRING or
      (type_.property_type == PropertyType.FUNCTION and
           type_.is_serializable_function)):
    s = '%s.GetIfString()'
  else:
    raise ValueError('Type %s is not a fundamental value' % type_.name)

  return s % src


def GetValueType(type_):
  """Returns the Value::Type corresponding to the model.Type.
  """
  if type_.property_type == PropertyType.ARRAY:
    return 'base::Value::Type::LIST'
  if type_.property_type == PropertyType.BINARY:
    return 'base::Value::Type::BINARY'
  if type_.property_type == PropertyType.BOOLEAN:
    return 'base::Value::Type::BOOLEAN'
  if type_.property_type == PropertyType.DOUBLE:
    return 'base::Value::Type::DOUBLE'
  if type_.property_type == PropertyType.ENUM:
    return 'base::Value::Type::STRING'
  if type_.property_type == PropertyType.FUNCTION:
    if type_.is_serializable_function:
      return 'base::Value::Type::STRING'
    return 'base::Value::Type::DICTIONARY'
  if type_.property_type == PropertyType.INTEGER:
    return 'base::Value::Type::INTEGER'
  if type_.property_type == PropertyType.OBJECT:
    return 'base::Value::Type::DICTIONARY'
  if type_.property_type == PropertyType.STRING:
    return 'base::Value::Type::STRING'

  raise ValueError('Invalid type: %s' % type_.name)

def ShouldUseAbslOptional(type_):
  """Called to validate whether or not an optional value should be represented
  with absl::optional. This function is a temporary utility, while optional
  fields are gradually migrated away from using std::unique_ptr.
  """

  if type_.property_type in (PropertyType.ANY,
                             PropertyType.ARRAY,
                             PropertyType.BINARY,
                             PropertyType.BOOLEAN,
                             PropertyType.CHOICES,
                             PropertyType.DOUBLE,
                             PropertyType.FUNCTION,
                             PropertyType.INTEGER,
                             PropertyType.OBJECT,
                             PropertyType.STRING):
    return True

  return False

def GetParameterDeclaration(param, type_):
  """Gets a parameter declaration of a given model.Property and its C++
  type.
  """
  if param.type_.property_type in (PropertyType.ANY,
                                   PropertyType.ARRAY,
                                   PropertyType.BINARY,
                                   PropertyType.CHOICES,
                                   PropertyType.OBJECT,
                                   PropertyType.REF,
                                   PropertyType.STRING):
    arg = 'const %(type)s& %(name)s'
  else:
    arg = '%(type)s %(name)s'
  return arg % {
    'type': type_,
    'name': param.unix_name,
  }


def GenerateIfndefName(file_path):
  """Formats |file_path| as a #define name. Presumably |file_path| is a header
  file, or there's little point in generating a #define for it.

  e.g chrome/extensions/gen/file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__.
  """
  return (('%s__' % file_path).upper()
      .replace('\\', '_')
      .replace('/', '_')
      .replace('-', '_')
      .replace('.', '_'))


def OpenNamespace(cpp_namespace):
  """Get opening root namespace declarations.
  """
  c = Code()
  for component in cpp_namespace.split('::'):
    c.Append('namespace %s {' % component)
  return c


def CloseNamespace(cpp_namespace):
  """Get closing root namespace declarations.
  """
  c = Code()
  for component in reversed(cpp_namespace.split('::')):
    c.Append('}  // namespace %s' % component)
  return c


def FeatureNameToConstantName(feature_name):
  # type: (str) -> str
  """Returns a kName for a feature's name.
  """
  return ('k' + ''.join(word[0].upper() + word[1:]
      for word in feature_name.replace('.', ' ').split()))


def UnixNameToConstantName(unix_name):
  # type (str) -> str
  """Converts unix_name to kUnixName.
  """
  return ('k' + ''.join(word.capitalize() for word in unix_name.split('_')))

def IsUnixName(s):
  # type (str) -> bool
  """Returns true if |s| is of the type unix_name i.e. only has lower cased
  characters and underscores with at least one underscore.
  """
  return all(x.islower() or x == '_' for x in s) and '_' in s

def ToPosixPath(path):
  """Returns |path| with separator converted to POSIX style.

  This is needed to generate C++ #include paths.
  """
  return path.replace(os.path.sep, posixpath.sep)


def CamelCase(unix_name):
  return ''.join(word.capitalize() for word in unix_name.split('_'))


def ClassName(filepath):
  return CamelCase(os.path.split(filepath)[1])


def GetCppNamespace(pattern, namespace):
  '''Returns the C++ namespace given |pattern| which includes a %(namespace)s
  substitution, and the |namespace| to substitute. It is expected that |pattern|
  has been passed as a flag to compiler.py from GYP/GN.
  '''
  # For some reason Windows builds escape the % characters, so unescape them.
  # This means that %% can never appear legitimately within a pattern, but
  # that's ok. It should never happen.
  cpp_namespace = pattern.replace('%%', '%') % { 'namespace': namespace }
  assert '%' not in cpp_namespace, \
         ('Did not manage to fully substitute namespace "%s" into pattern "%s"'
           % (namespace, pattern))
  return cpp_namespace
