#!/usr/bin/env python3
# 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.

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 namespace 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'
  ]

  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().items():
          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
