#!/usr/bin/python
# Copyright (c) 2011, 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.

"""Module to manage IDL files."""

import copy
import pickle
import logging
import os
import os.path
import shutil
import idlnode
import idlrenderer
from generator import IsDartCollectionType, IsPureInterface

_logger = logging.getLogger('database')


class Database(object):
  """The Database class manages a collection of IDL files stored
  inside a directory.

  Each IDL is describing a single interface. The IDL files are written in the
  FremontCut syntax, which is derived from the Web IDL syntax and includes
  annotations.

  Database operations include adding, updating and removing IDL files.
  """

  def __init__(self, root_dir):
    """Initializes a Database over a given directory.

    Args:
      root_dir -- a directory. If directory does not exist, it will
      be created.
    """
    self._root_dir = root_dir
    if not os.path.exists(root_dir):
      _logger.debug('creating root directory %s' % root_dir)
      os.makedirs(root_dir)
    self._all_interfaces = {}
    self._interfaces_to_delete = []
    self._enums = {}
    self._all_dictionaries = {}
    # TODO(terry): Hack to remember all typedef unions.
    self._all_type_defs = {}

  def Clone(self):
    new_database = Database(self._root_dir)
    new_database._all_interfaces = copy.deepcopy(self._all_interfaces)
    new_database._interfaces_to_delete = copy.deepcopy(
        self._interfaces_to_delete)
    new_database._enums = copy.deepcopy(self._enums)
    new_database._all_dictionaries = copy.deepcopy(self._all_dictionaries)
    new_database._all_type_defs = copy.deepcopy(self._all_type_defs)

    return new_database

  def Delete(self):
    """Deletes the database by deleting its directory"""
    if os.path.exists(self._root_dir):
      shutil.rmtree(self._root_dir)
    # reset in-memory constructs
    self._all_interfaces = {}

  def _ScanForInterfaces(self):
    """Iteratores over the database files and lists all interface names.

    Return:
      A list of interface names.
    """
    res = []

    def Visitor(_, dirname, names):
      for name in names:
        if os.path.isfile(os.path.join(dirname, name)):
          root, ext = os.path.splitext(name)
          if ext == '.idl':
            res.append(root)

    os.path.walk(self._root_dir, Visitor, None)
    return res

  def _FilePath(self, interface_name):
    """Calculates the file path that a given interface should
    be saved to.

    Args:
      interface_name -- the name of the interface.
    """
    return os.path.join(self._root_dir, '%s.idl' % interface_name)

  def _LoadInterfaceFile(self, interface_name):
    """Loads an interface from the database.

    Returns:
      An IDLInterface instance or None if the interface is not found.
    Args:
      interface_name -- the name of the interface.
    """
    file_name = self._FilePath(interface_name)
    _logger.info('loading %s' % file_name)
    if not os.path.exists(file_name):
      return None

    f = open(file_name, 'r')
    content = f.read()
    f.close()

    # Parse file:
    idl_file = idlnode.IDLFile(self._idlparser.parse(content), file_name)

    if not idl_file.interfaces:
      raise RuntimeError('No interface found in %s' % file_name)
    elif len(idl_file.interfaces) > 1:
      raise RuntimeError('Expected one interface in %s' % file_name)

    interface = idl_file.interfaces[0]
    self._all_interfaces[interface_name] = interface
    return interface

  def Load(self):
    """Loads all interfaces into memory.
    """
    # FIXME: Speed this up by multi-threading.
    for (interface_name) in self._ScanForInterfaces():
      self._LoadInterfaceFile(interface_name)
    self.Cache()

  def Cache(self):
    """Serialize the database using pickle for faster startup in the future
    """
    output_file = open(os.path.join(self._root_dir, 'cache.pickle'), 'wb')
    pickle.dump(self._all_interfaces, output_file)
    pickle.dump(self._interfaces_to_delete, output_file)

  def LoadFromCache(self):
    """Deserialize the database using pickle for fast startup
    """
    input_file_name = os.path.join(self._root_dir, 'cache.pickle')
    if not os.path.isfile(input_file_name):
      self.Load()
      return
    input_file = open(input_file_name, 'rb')
    self._all_interfaces = pickle.load(input_file)
    self._interfaces_to_delete = pickle.load(input_file)
    input_file.close()

  def Save(self):
    """Saves all in-memory interfaces into files."""
    for interface in self._all_interfaces.values():
      self._SaveInterfaceFile(interface)
    for interface_name in self._interfaces_to_delete:
      self._DeleteInterfaceFile(interface_name)

  def _SaveInterfaceFile(self, interface):
    """Saves an interface into the database.

    Args:
      interface -- an IDLInterface instance.
    """

    interface_name = interface.id

    # Actual saving
    file_path = self._FilePath(interface_name)
    _logger.debug('writing %s' % file_path)

    dir_name = os.path.dirname(file_path)
    if not os.path.exists(dir_name):
      _logger.debug('creating directory %s' % dir_name)
      os.mkdir(dir_name)

    # Render the IDLInterface object into text.
    text = idlrenderer.render(interface)

    f = open(file_path, 'w')
    f.write(text)
    f.close()

  def HasInterface(self, interface_name):
    """Returns True if the interface is in memory"""
    return interface_name in self._all_interfaces

  def GetInterface(self, interface_name):
    """Returns an IDLInterface corresponding to the interface_name
    from memory.

    Args:
      interface_name -- the name of the interface.
    """
    if interface_name not in self._all_interfaces:
      raise RuntimeError('Interface %s is not loaded' % interface_name)
    return self._all_interfaces[interface_name]

  def AddInterface(self, interface):
    """Returns an IDLInterface corresponding to the interface_name
    from memory.

    Args:
      interface -- the name of the interface.
    """
    interface_name = interface.id
    if interface_name in self._all_interfaces:
      raise RuntimeError('Interface %s already exists' % interface_name)
    self._all_interfaces[interface_name] = interface

  def GetInterfaces(self):
    """Returns a list of all loaded interfaces."""
    res = []
    for _, interface in sorted(self._all_interfaces.items()):
      res.append(interface)
    return res

  def DeleteInterface(self, interface_name):
    """Deletes an interface from the database. File is deleted when
    Save() is called.

    Args:
      interface_name -- the name of the interface.
    """
    if interface_name not in self._all_interfaces:
      raise RuntimeError('Interface %s not found' % interface_name)
    self._interfaces_to_delete.append(interface_name)
    del self._all_interfaces[interface_name]

  def _DeleteInterfaceFile(self, interface_name):
    """Actual file deletion"""
    file_path = self._FilePath(interface_name)
    if os.path.exists(file_path):
      _logger.debug('deleting %s' % file_path)
      os.remove(file_path)

  def Hierarchy(self, interface):
    yield interface
    for parent in interface.parents:
      parent_name = parent.type.id
      if not self.HasInterface(parent.type.id):
        continue
      for parent_interface in self.Hierarchy(self.GetInterface(parent.type.id)):
        yield parent_interface

  def HasEnum(self, enum_name):
    return enum_name in self._enums

  def GetEnum(self, enum_name):
    return self._enums[enum_name]

  def AddEnum(self, enum):
    self._enums[enum.id] = enum

  def HasDictionary(self, dictionary_name):
    """Returns True if the dictionary is in memory"""
    return dictionary_name in self._all_dictionaries

  def GetDictionary(self, dictionary_name):
    """Returns an IDLDictionary corresponding to the dictionary_name
    from memory.

    Args:
      dictionary_name -- the name of the dictionary.
    """
    if dictionary_name not in self._all_dictionaries:
      raise RuntimeError('Dictionary %s is not loaded' % dictionary_name)
    return self._all_dictionaries[dictionary_name]

  def AddDictionary(self, dictionary):
    """Returns an IDLDictionary corresponding to the dictionary_name
    from memory.

    Args:
      dictionary -- the name of the dictionary.
    """
    dictionary_name = dictionary.id
    if dictionary_name in self._all_dictionaries:
      raise RuntimeError('Dictionary %s already exists' % dictionary_name)
    self._all_dictionaries[dictionary_name] = dictionary

  def GetDictionaries(self):
    """Returns a list of all loaded dictionaries."""
    res = []
    for _, dictionary in sorted(self._all_dictionaries.items()):
      res.append(dictionary)
    return res

  def HasTypeDef(self, type_def_name):
    """Returns True if the typedef is in memory"""
    return type_def_name in self._all_type_defs

  def GetTypeDef(self, type_def_name):
    """Returns an IDLTypeDef corresponding to the type_def_name
    from memory.

    Args:
      type_def_name -- the name of the typedef.
    """
    if type_def_name not in self._all_type_defs:
      raise RuntimeError('Typedef %s is not loaded' % type_def_name)
    return self._all_type_defs[type_def_name]

  def AddTypeDef(self, type_def):
    """Add only a typedef that a unions they map to any (no type)."""
    type_def_name = type_def.id
    if type_def_name in self._all_type_defs:
      raise RuntimeError('Typedef %s already exists' % type_def_name)
    self._all_type_defs[type_def_name] = type_def
    print '  Added typedef %s' % type_def_name

  def TransitiveSecondaryParents(self, interface, propagate_event_target):
    """Returns a list of all non-primary parents.

    The list contains the interface objects for interfaces defined in the
    database, and the name for undefined interfaces.
    """
    def walk(parents, walk_result):
      for parent in parents:
        parent_name = parent.type.id
        if IsDartCollectionType(parent_name):
          if not(parent_name in walk_result):
            walk_result.append(parent_name)
          continue
        if self.HasInterface(parent_name):
          parent_interface = self.GetInterface(parent_name)
          if not(parent_interface in walk_result):
            # Interface has multi-inherited don't add interfaces more than once
            # to our parent result list.
            walk_result.append(parent_interface)
          walk(parent_interface.parents, walk_result)
      return walk_result

    result = []
    if interface.parents:
      parent = interface.parents[0]
      if (IsPureInterface(parent.type.id, self) or
          (propagate_event_target and parent.type.id == 'EventTarget')):
        result = walk(interface.parents, [])
      else:
        result = walk(interface.parents[1:], [])

    return result

