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

from __future__ import print_function

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:]))
