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

import sys

#
# IDL Node
#
# IDL Node defines the IDLAttribute and IDLNode objects which are constructed
# by the parser as it processes the various 'productions'.  The IDLAttribute
# objects are assigned to the IDLNode's property dictionary instead of being
# applied as children of The IDLNodes, so they do not exist in the final tree.
# The AST of IDLNodes is the output from the parsing state and will be used
# as the source data by the various generators.
#


#
# CopyToList
#
# Takes an input item, list, or None, and returns a new list of that set.
def CopyToList(item):
  # If the item is 'Empty' make it an empty list
  if not item:
    item = []

  # If the item is not a list
  if type(item) is not type([]):
    item = [item]

  # Make a copy we can modify
  return list(item)


# IDLSearch
#
# A temporary object used by the parsing process to hold an Extended Attribute
# which will be passed as a child to a standard IDLNode.
#
class IDLSearch(object):
  def __init__(self):
    self.depth = 0

  def Enter(self, node):
    pass

  def Exit(self, node):
    pass


# IDLAttribute
#
# A temporary object used by the parsing process to hold an Extended Attribute
# which will be passed as a child to a standard IDLNode.
#
class IDLAttribute(object):
  def __init__(self, name, value):
    self._cls = 'Property'
    self.name = name
    self.value = value

  def __str__(self):
    return '%s=%s' % (self.name, self.value)

  def GetClass(self):
    return self._cls

#
# IDLNode
#
# This class implements the AST tree, providing the associations between
# parents and children.  It also contains a namepsace and propertynode to
# allow for look-ups.  IDLNode is derived from IDLRelease, so it is
# version aware.
#
class IDLNode(object):
  VERBOSE_PROPS = [
      'PROD', 'NAME', 'VALUE', 'TYPE',
      'ERRORS', 'WARNINGS', 'FILENAME', 'LINENO', 'POSITION', 'DATETIME',
  ]

  def __init__(self, cls, filename, lineno, pos, children=None):
    self._cls = cls
    self._properties = {
      'ERRORS' : [],
      'WARNINGS': [],
      'FILENAME': filename,
      'LINENO' : lineno,
      'POSITION' : pos,
    }

    self._children = []
    self._parent = None
    self.AddChildren(children)

#
#
#
  # Return a string representation of this node
  def __str__(self):
    name = self.GetProperty('NAME','')
    value = self.GetProperty('VALUE')
    if value or value == '':
      return '%s(%s) = "%s"' % (self._cls, name, value)
    return '%s(%s)' % (self._cls, name)

  def GetLogLine(self, msg):
    filename, lineno = self.GetFileAndLine()
    return '%s(%d) : %s\n' % (filename, lineno, msg)

  # Log an error for this object
  def Error(self, msg):
    self.GetProperty('ERRORS').append(msg)
    sys.stderr.write(self.GetLogLine('error: ' + msg))

  # Log a warning for this object
  def Warning(self, msg):
    self.GetProperty('WARNINGS').append(msg)
    sys.stdout.write(self.GetLogLine('warning:' + msg))

  # Return file and line number for where node was defined
  def GetFileAndLine(self):
    return self.GetProperty('FILENAME'), self.GetProperty('LINENO')

  def GetClass(self):
    return self._cls

  def GetName(self):
    return self.GetProperty('NAME')

  def GetParent(self):
    return self._parent

  def Traverse(self, search, filter_nodes):
    if self._cls in filter_nodes:
      return ''

    search.Enter(self)
    search.depth += 1
    for child in self._children:
      child.Traverse(search, filter_nodes)
    search.depth -= 1
    search.Exit(self)


  def Tree(self, filter_nodes=None, suppress_props=VERBOSE_PROPS):
    class DumpTreeSearch(IDLSearch):
      def __init__(self, props):
        IDLSearch.__init__(self)
        self.out = []
        self.props = props or []

      def Enter(self, node):
        tab = ''.rjust(self.depth * 2)
        self.out.append(tab + str(node))

        proplist = []
        for key, value in node.GetProperties().iteritems():
          if key not in self.props:
            proplist.append(tab + '  %s: %s' % (key, str(value)))
        if proplist:
          self.out.extend(proplist)

    if filter_nodes == None:
      filter_nodes = ['SpecialComment']

    search = DumpTreeSearch(suppress_props)
    self.Traverse(search, filter_nodes)
    return search.out

#
# Search related functions
#
  # Check if node is of a given type
  def IsA(self, *typelist):
    if self._cls in typelist:
      return True
    return False

  # Get a list of all children
  def GetChildren(self):
    return self._children

  def GetListOf(self, *keys):
    out = []
    for child in self.GetChildren():
      if child.GetClass() in keys:
        out.append(child)
    return out

  def GetOneOf(self, *keys):
    out = self.GetListOf(*keys)
    if out:
      return out[0]
    return None

  def AddChildren(self, children):
    children = CopyToList(children)
    for child in children:
      if not child:
        continue
      if type(child) == IDLAttribute:
        self.SetProperty(child.name, child.value)
        continue
      if type(child) == IDLNode:
        child._parent = self
        self._children.append(child)
        continue
      raise RuntimeError('Adding child of type %s.\n' % type(child).__name__)


#
# Property Functions
#
  def SetProperty(self, name, val):
    self._properties[name] = val

  def GetProperty(self, name, default=None):
    return self._properties.get(name, default)

  def GetProperties(self):
    return self._properties
