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

from code import Code
from model import PropertyType

from datetime import datetime

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

INFO = """// This file was generated by:
//   %s.
"""


class JsUtil(object):
  """A helper class for generating JS Code.
  """
  def GetLicense(self):
    """Returns the license text for JS extern and interface files.
    """
    return (LICENSE % datetime.now().year)

  def GetInfo(self, tool):
    """Returns text describing how the file was generated.
    """
    return (INFO % tool)

  def AppendObjectDefinition(self, c, namespace_name, properties,
                               new_line=True):
    """Given an OrderedDict of properties, returns a Code containing the
       description of an object.
    """
    if not properties: return

    c.Sblock('{', new_line=new_line)
    first = True
    for field, prop in properties.items():
      # Avoid trailing comma.
      # TODO(devlin): This will be unneeded, if/when
      # https://github.com/google/closure-compiler/issues/796 is fixed.
      if not first:
        c.Append(',', new_line=False)
      first = False
      js_type = self._TypeToJsType(namespace_name, prop.type_)
      if prop.optional:
        js_type = (Code().Append('(')
                         .Concat(js_type, new_line=False)
                         .Append('|undefined)', new_line=False))
      c.Append('%s: ' % field, strip_right=False)
      c.Concat(js_type, new_line=False)

    c.Eblock('}')

  def AppendFunctionJsDoc(self, c, namespace_name, function):
    """Appends the documentation for a function as a Code.

    Returns an empty code object if the object has no documentation.
    """
    c.Sblock(line='/**', line_prefix=' * ')

    if function.description:
      c.Comment(function.description, comment_prefix='')

    def append_field(c, tag, js_type, name, optional, description):
      c.Append('@%s {' % tag)
      c.Concat(js_type, new_line=False)
      if optional:
        c.Append('=', new_line=False)
      c.Append('}', new_line=False)
      c.Comment(' %s' % name, comment_prefix='', wrap_indent=4, new_line=False)
      if description:
        c.Comment(' %s' % description, comment_prefix='',
                  wrap_indent=4, new_line=False)

    for param in function.params:
      append_field(c, 'param',
                   self._TypeToJsType(namespace_name, param.type_),
                   param.name, param.optional, param.description)

    if function.callback:
      append_field(c, 'param',
                   self._FunctionToJsFunction(namespace_name,
                                              function.callback),
                   function.callback.name, function.callback.optional,
                   function.callback.description)

    if function.returns:
      append_field(c, 'return',
                   self._TypeToJsType(namespace_name, function.returns),
                   '', False, function.returns.description)

    if function.deprecated:
      c.Append('@deprecated %s' % function.deprecated)

    self.AppendSeeLink(c, namespace_name, 'method', function.name)

    c.Eblock(' */')

  def AppendTypeJsDoc(self, c, namespace_name, js_type, optional):
    """Appends the documentation for a type as a Code.
    """
    c.Append('@type {')
    if optional:
      c.Append('(', new_line=False)
      c.Concat(self._TypeToJsType(namespace_name, js_type), new_line=False)
      c.Append('|undefined)', new_line=False)
    else:
      c.Concat(self._TypeToJsType(namespace_name, js_type), new_line=False)
    c.Append('}', new_line=False)

  def _FunctionToJsFunction(self, namespace_name, function):
    """Converts a model.Function to a JS type (i.e., function([params])...)"""
    c = Code()
    c.Append('function(')
    for i, param in enumerate(function.params):
      t = self._TypeToJsType(namespace_name, param.type_)
      if param.optional:
        c.Append('(', new_line=False)
        c.Concat(t, new_line=False)
        c.Append('|undefined)', new_line=False)
      else:
        c.Concat(t, new_line = False)
      if i is not len(function.params) - 1:
        c.Append(', ', new_line=False, strip_right=False)
    c.Append('):', new_line=False)

    if function.returns:
      c.Concat(self._TypeToJsType(namespace_name, function.returns),
               new_line=False)
    else:
      c.Append('void', new_line=False)

    return c

  def _TypeToJsType(self, namespace_name, js_type):
    """Converts a model.Type to a JS type (number, Array, etc.)"""
    if js_type.property_type in (PropertyType.INTEGER, PropertyType.DOUBLE):
      return Code().Append('number')
    if js_type.property_type is PropertyType.OBJECT:
      if js_type.properties:
        c = Code()
        self.AppendObjectDefinition(c, namespace_name, js_type.properties)
        return c
      return Code().Append('Object')
    if js_type.property_type is PropertyType.ARRAY:
      return (Code().Append('!Array<').
              Concat(self._TypeToJsType(namespace_name, js_type.item_type),
                     new_line=False).
           Append('>', new_line=False))
    if js_type.property_type is PropertyType.REF:
      ref_type = '!chrome.%s.%s' % (namespace_name, js_type.ref_type)
      return Code().Append(ref_type)
    if js_type.property_type is PropertyType.CHOICES:
      c = Code()
      c.Append('(')
      for i, choice in enumerate(js_type.choices):
        c.Concat(self._TypeToJsType(namespace_name, choice), new_line=False)
        if i is not len(js_type.choices) - 1:
          c.Append('|', new_line=False)
      c.Append(')', new_line=False)
      return c
    if js_type.property_type is PropertyType.FUNCTION:
      return self._FunctionToJsFunction(namespace_name, js_type.function)
    if js_type.property_type is PropertyType.BINARY:
      return Code().Append('ArrayBuffer')
    if js_type.property_type is PropertyType.ANY:
      return Code().Append('*')
    if js_type.property_type.is_fundamental:
      return Code().Append(js_type.property_type.name)
    return Code().Append('?') # TODO(tbreisacher): Make this more specific.

  def AppendSeeLink(self, c, namespace_name, object_type, object_name):
    """Appends a @see link for a given API 'object' (type, method, or event).
    """

    # TODO(nigeltao): this should actually be gated on if there is
    # documentation, rather than if it's a private API. Most private APIs
    # aren't documented, but some are. For example:
    #  - https://developer.chrome.com/apps/developerPrivate exists
    #  - https://developer.chrome.com/apps/screenlockPrivate does not
    if namespace_name.endswith('Private'):
      return

    # NOTE(devlin): This is kind of a hack. Some APIs will be hosted on
    # developer.chrome.com/apps/ instead of /extensions/, and some APIs have
    # '.'s in them (like app.window), which should resolve to 'app_window'.
    # Luckily, the doc server has excellent url resolution, and knows exactly
    # what we mean. This saves us from needing any complicated logic here.
    c.Append('@see https://developer.chrome.com/extensions/%s#%s-%s' %
             (namespace_name, object_type, object_name))
