#!/usr/bin/python
# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

"""This module provides base functionality for systems to generate
Dart APIs from the IDL database."""

import os
#import re
from generator_java import *


def MassagePath(path):
  # The most robust way to emit path separators is to use / always.
  return path.replace('\\', '/')

class SystemElemental(object):
  """A System generates all the files for one implementation.

  This is a base class for all the specific systems.
  The life-cycle of a System is:
  - construction (__init__)
  - (InterfaceGenerator | ProcessCallback)*  # for each IDL interface
  - GenerateLibraries
  - Finish
  """

  def __init__(self, templates, database, emitters, output_dir):
    self._templates = templates
    self._database = database
    self._emitters = emitters
    self._output_dir = output_dir
    self._dart_callback_file_paths = []

  def InterfaceGenerator(self,
                         interface,
                         common_prefix,
                         super_interface_name,
                         source_filter):
    """Returns an interface generator for |interface|.

    Called once for each interface that is not a callback function.
    """
    return None

  def ProcessCallback(self, interface, info):
    """Processes an interface that is a callback function."""
    pass

  def GenerateLibraries(self, lib_dir):
    pass

  def Finish(self):
    pass


  # Helper methods used by several systems.

  def _ProcessCallback(self, interface, info, file_path):
    """Generates a typedef for the callback interface."""
    self._dart_callback_file_paths.append(file_path)
    code = self._emitters.FileEmitter(file_path)

    code.Emit(self._templates.Load('callback.darttemplate'))
    code.Emit('typedef $TYPE $NAME($PARAMS);\n',
              NAME=interface.id,
              TYPE=info.type_name,
              PARAMS=info.ParametersImplementationDeclaration())


  def _GenerateLibFile(self, lib_template, lib_file_path, file_paths,
                       **template_args):
    """Generates a lib file from a template and a list of files.

    Additional keyword arguments are passed to the template.
    Typically called from self.GenerateLibraries.
    """
    # Load template.
    template = self._templates.Load(lib_template)
    # Generate the .lib file.
    lib_file_contents = self._emitters.FileEmitter(lib_file_path)

    # Emit the list of #source directives.
    list_emitter = lib_file_contents.Emit(template, **template_args)
    lib_file_dir = os.path.dirname(lib_file_path)
    for path in sorted(file_paths):
      relpath = os.path.relpath(path, lib_file_dir)
      list_emitter.Emit("#source('$PATH');\n", PATH=MassagePath(relpath))

      
  def _BaseDefines(self, interface):
    """Returns a set of names (strings) for members defined in a base class.
    """
    def WalkParentChain(interface):
      if interface.parents:
        # Only consider primary parent, secondary parents are not on the
        # implementation class inheritance chain.
        parent = interface.parents[0]
        if generator.IsDartCollectionType(parent.type.id):
          return
        if self._database.HasInterface(parent.type.id):
          parent_interface = self._database.GetInterface(parent.type.id)
          for attr in parent_interface.attributes:
            result.add(attr.id)
          for op in parent_interface.operations:
            result.add(op.id)
          WalkParentChain(parent_interface)

    result = set()
    WalkParentChain(interface)
    return result;

  def ProcessMixins(self, mixins):
    """Handle interfaces which must be hoisted to a common JSO base class"""
    self._mixins = mixins


class ElementalBase(object):
  def __init__(self):
    self.reserved_keywords = []
    self.reserved_keywords = ['continue', 'delete', 'for', 'while', 'do', 'class', 'switch', 'try', 'catch', 'finally',
                'int', 'float', 'short', 'double', 'char', 'byte', 'long', 'implements', 'extends', 'throws', 'case', 'if',
                'else', 'throw', 'instanceof', 'true', 'false', 'default', 'null', 'abstract', 'package', 'super',
                'public', 'protected', 'private', 'volatile', 'transient', 'final', 'synchronized', 'import', 'enum', 'boolean', 'assert']

  def getImplements(self, alreadyImplemented, iface):
    if '<' in iface.type.id:
      return DartType(iface.type.id)
    if iface.type.id in alreadyImplemented:
      return
    alreadyImplemented[iface.type.id]=1
    piface = self._database.GetInterface(iface.type.id)
    for parent in piface.parents:
        self.getImplements(alreadyImplemented, parent)

  def fixReservedKeyWords(self, name):
    if name in ['continue', 'delete', 'for', 'while', 'do', 'class', 'switch', 'try', 'catch', 'finally',
                'int', 'float', 'short', 'double', 'char', 'byte', 'long', 'implements', 'extends', 'throws', 'case', 'if',
                'else', 'throw', 'instanceof', 'true', 'false', 'default', 'null', 'abstract', 'package', 'super',
                'public', 'protected', 'private', 'volatile', 'transient', 'final', 'synchronized', 'import', 'enum', 'boolean', 'assert']:
      return '_' + name;
    return name



