#!/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.

"""
IDLNamespace for PPAPI

This file defines the behavior of the AST namespace which allows for resolving
a symbol as one or more AST nodes given a release or range of releases.
"""

import sys

from idl_option import GetOption, Option, ParseOptions
from idl_log import ErrOut, InfoOut, WarnOut
from idl_release import IDLRelease, IDLReleaseList

Option('label', 'Use the specifed label blocks.', default='Chrome')
Option('namespace_debug', 'Use the specified release')


#
# IDLNamespace
#
# IDLNamespace provides a mapping between a symbol name and an IDLReleaseList
# which contains IDLRelease objects.  It provides an interface for fetching
# one or more IDLNodes based on a release or range of releases.
#
class IDLNamespace(object):
  def __init__(self, parent):
    self._name_to_releases = {}
    self._parent = parent

  def Dump(self):
    for name in self._name_to_releases:
      InfoOut.Log('NAME=%s' % name)
      for cver in self._name_to_releases[name].GetReleases():
        InfoOut.Log('  %s' % cver)
      InfoOut.Log('')

  def FindRelease(self, name, release):
    verlist = self._name_to_releases.get(name, None)
    if verlist == None:
      if self._parent:
        return self._parent.FindRelease(name, release)
      else:
        return None
    return verlist.FindRelease(release)

  def FindRange(self, name, rmin, rmax):
    verlist = self._name_to_releases.get(name, None)
    if verlist == None:
      if self._parent:
        return self._parent.FindRange(name, rmin, rmax)
      else:
        return []
    return verlist.FindRange(rmin, rmax)

  def FindList(self, name):
    verlist = self._name_to_releases.get(name, None)
    if verlist == None:
      if self._parent:
        return self._parent.FindList(name)
    return verlist

  def AddNode(self, node):
    name = node.GetName()
    verlist = self._name_to_releases.setdefault(name,IDLReleaseList())
    if GetOption('namespace_debug'):
        print "Adding to namespace: %s" % node
    return verlist.AddNode(node)


#
# Testing Code
#

#
# MockNode
#
# Mocks the IDLNode to support error, warning handling, and string functions.
#
class MockNode(IDLRelease):
  def __init__(self, name, rmin, rmax):
    self.name = name
    self.rmin = rmin
    self.rmax = rmax
    self.errors = []
    self.warns = []
    self.properties = {
        'NAME': name,
        'release': rmin,
        'deprecate' : rmax
        }

  def __str__(self):
    return '%s (%s : %s)' % (self.name, self.rmin, self.rmax)

  def GetName(self):
    return self.name

  def Error(self, msg):
    if GetOption('release_debug'): print 'Error: %s' % msg
    self.errors.append(msg)

  def Warn(self, msg):
    if GetOption('release_debug'): print 'Warn: %s' % msg
    self.warns.append(msg)

  def GetProperty(self, name):
    return self.properties.get(name, None)

errors = 0
#
# DumpFailure
#
# Dumps all the information relevant  to an add failure.
def DumpFailure(namespace, node, msg):
  global errors
  print '\n******************************'
  print 'Failure: %s %s' % (node, msg)
  for warn in node.warns:
    print '  WARN: %s' % warn
  for err in node.errors:
    print '  ERROR: %s' % err
  print '\n'
  namespace.Dump()
  print '******************************\n'
  errors += 1

# Add expecting no errors or warnings
def AddOkay(namespace, node):
  okay = namespace.AddNode(node)
  if not okay or node.errors or node.warns:
    DumpFailure(namespace, node, 'Expected success')

# Add expecting a specific warning
def AddWarn(namespace, node, msg):
  okay = namespace.AddNode(node)
  if not okay or node.errors or not node.warns:
    DumpFailure(namespace, node, 'Expected warnings')
  if msg not in node.warns:
    DumpFailure(namespace, node, 'Expected warning: %s' % msg)

# Add expecting a specific error any any number of warnings
def AddError(namespace, node, msg):
  okay = namespace.AddNode(node)
  if okay or not node.errors:
    DumpFailure(namespace, node, 'Expected errors')
  if msg not in node.errors:
    DumpFailure(namespace, node, 'Expected error: %s' % msg)
    print ">>%s<<\n>>%s<<\n" % (node.errors[0], msg)

# Verify that a FindRelease call on the namespace returns the expected node.
def VerifyFindOne(namespace, name, release, node):
  global errors
  if (namespace.FindRelease(name, release) != node):
    print "Failed to find %s as release %f of %s" % (node, release, name)
    namespace.Dump()
    print "\n"
    errors += 1

# Verify that a FindRage call on the namespace returns a set of expected nodes.
def VerifyFindAll(namespace, name, rmin, rmax, nodes):
  global errors
  out = namespace.FindRange(name, rmin, rmax)
  if (out != nodes):
    print "Found [%s] instead of[%s] for releases %f to %f of %s" % (
        ' '.join([str(x) for x in out]),
        ' '.join([str(x) for x in nodes]),
        rmin,
        rmax,
        name)
    namespace.Dump()
    print "\n"
    errors += 1

def Main(args):
  global errors
  ParseOptions(args)

  InfoOut.SetConsole(True)

  namespace = IDLNamespace(None)

  FooXX = MockNode('foo', None, None)
  Foo1X = MockNode('foo', 1.0, None)
  Foo2X = MockNode('foo', 2.0, None)
  Foo3X = MockNode('foo', 3.0, None)

  # Verify we succeed with undeprecated adds
  AddOkay(namespace, FooXX)
  AddOkay(namespace, Foo1X)
  AddOkay(namespace, Foo3X)
  # Verify we fail to add a node between undeprecated releases
  AddError(namespace, Foo2X,
           'Overlap in releases: 3.0 vs 2.0 when adding foo (2.0 : None)')

  BarXX = MockNode('bar', None, None)
  Bar12 = MockNode('bar', 1.0, 2.0)
  Bar23 = MockNode('bar', 2.0, 3.0)
  Bar34 = MockNode('bar', 3.0, 4.0)


  # Verify we succeed with fully qualified releases
  namespace = IDLNamespace(namespace)
  AddOkay(namespace, BarXX)
  AddOkay(namespace, Bar12)
  # Verify we warn when detecting a gap
  AddWarn(namespace, Bar34, 'Gap in release numbers.')
  # Verify we fail when inserting into this gap
  # (NOTE: while this could be legal, it is sloppy so we disallow it)
  AddError(namespace, Bar23, 'Declarations out of order.')

  # Verify local namespace
  VerifyFindOne(namespace, 'bar', 0.0, BarXX)
  VerifyFindAll(namespace, 'bar', 0.5, 1.5, [BarXX, Bar12])

  # Verify the correct release of the object is found recursively
  VerifyFindOne(namespace, 'foo', 0.0, FooXX)
  VerifyFindOne(namespace, 'foo', 0.5, FooXX)
  VerifyFindOne(namespace, 'foo', 1.0, Foo1X)
  VerifyFindOne(namespace, 'foo', 1.5, Foo1X)
  VerifyFindOne(namespace, 'foo', 3.0, Foo3X)
  VerifyFindOne(namespace, 'foo', 100.0, Foo3X)

  # Verify the correct range of objects is found
  VerifyFindAll(namespace, 'foo', 0.0, 1.0, [FooXX])
  VerifyFindAll(namespace, 'foo', 0.5, 1.0, [FooXX])
  VerifyFindAll(namespace, 'foo', 1.0, 1.1, [Foo1X])
  VerifyFindAll(namespace, 'foo', 0.5, 1.5, [FooXX, Foo1X])
  VerifyFindAll(namespace, 'foo', 0.0, 3.0, [FooXX, Foo1X])
  VerifyFindAll(namespace, 'foo', 3.0, 100.0, [Foo3X])

  FooBar = MockNode('foobar', 1.0, 2.0)
  namespace = IDLNamespace(namespace)
  AddOkay(namespace, FooBar)

  if errors:
    print 'Test failed with %d errors.' % errors
  else:
    print 'Passed.'
  return errors


if __name__ == '__main__':
  sys.exit(Main(sys.argv[1:]))

