#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

"""
Simple DOM for both SGML and XML documents.
"""

from __future__ import division
from __future__ import generators
from __future__ import nested_scopes
from __future__ import absolute_import

import sys
if sys.version_info[0] == 2:
    STRING_TYPES = (basestring,)
else:
    STRING_TYPES = (str,)

class Container:

  def __init__(self):
    self.children = []

  def add(self, child):
    child.parent = self
    self.children.append(child)

  def extend(self, children):
    for child in children:
      child.parent = self
      self.children.append(child)

class Component:

  def __init__(self):
    self.parent = None

  def index(self):
    if self.parent:
      return self.parent.children.index(self)
    else:
      return 0

  def _line(self, file, line, column):
    self.file = file
    self.line = line
    self.column = column

class DispatchError(Exception):

  def __init__(self, scope, f):
    msg = "no such attribtue"

class Dispatcher:

  def is_type(self, type):
    cls = self
    while cls != None:
      if cls.type == type:
        return True
      cls = cls.base
    return False

  def dispatch(self, f, attrs = ""):
    cls = self
    while cls != None:
      if hasattr(f, cls.type):
        return getattr(f, cls.type)(self)
      else:
        cls = cls.base

    cls = self
    while cls != None:
      if attrs:
        sep = ", "
        if cls.base == None:
          sep += "or "
      else:
        sep = ""
      attrs += "%s'%s'" % (sep, cls.type)
      cls = cls.base

    raise AttributeError("'%s' object has no attribute %s" %
                         (f.__class__.__name__, attrs))

class Node(Container, Component, Dispatcher):

  type = "node"
  base = None

  def __init__(self):
    Container.__init__(self)
    Component.__init__(self)
    self.query = Query([self])

  def __getitem__(self, name):
    for nd in self.query[name]:
      return nd

  def text(self):
    from . import transforms
    return self.dispatch(transforms.Text())

  def tag(self, name, *attrs, **kwargs):
    t = Tag(name, *attrs, **kwargs)
    self.add(t)
    return t

  def data(self, s):
    d = Data(s)
    self.add(d)
    return d

  def entity(self, s):
    e = Entity(s)
    self.add(e)
    return e

class Tree(Node):

  type = "tree"
  base = Node

class Tag(Node):

  type = "tag"
  base = Node

  def __init__(self, _name, *attrs, **kwargs):
    Node.__init__(self)
    self.name = _name
    self.attrs = list(attrs)
    self.attrs.extend(kwargs.items())
    self.singleton = False

  def get_attr(self, name):
    for k, v in self.attrs:
      if name == k:
        return v

  def _idx(self, attr):
    idx = 0
    for k, v in self.attrs:
      if k == attr:
        return idx
      idx += 1
    return None

  def set_attr(self, name, value):
    idx = self._idx(name)
    if idx is None:
      self.attrs.append((name, value))
    else:
      self.attrs[idx] = (name, value)

  def dispatch(self, f):
    try:
      attr = "do_" + self.name
      method = getattr(f, attr)
    except AttributeError:
      return Dispatcher.dispatch(self, f, "'%s'" % attr)
    return method(self)

class Leaf(Component, Dispatcher):

  type = "leaf"
  base = None

  def __init__(self, data):
    assert isinstance(data, STRING_TYPES)
    self.data = data

class Data(Leaf):
  type = "data"
  base = Leaf

class Entity(Leaf):
  type = "entity"
  base = Leaf

class Character(Leaf):
  type = "character"
  base = Leaf

class Comment(Leaf):
  type = "comment"
  base = Leaf

###################
## Query Classes ##
###########################################################################

class Adder:

  def __add__(self, other):
    return Sum(self, other)

class Sum(Adder):

  def __init__(self, left, right):
    self.left = left
    self.right = right

  def __iter__(self):
    for x in self.left:
      yield x
    for x in self.right:
      yield x

class View(Adder):

  def __init__(self, source):
    self.source = source

class Filter(View):

  def __init__(self, predicate, source):
    View.__init__(self, source)
    self.predicate = predicate

  def __iter__(self):
    for nd in self.source:
      if self.predicate(nd): yield nd

class Flatten(View):

  def __iter__(self):
    sources = [iter(self.source)]
    while sources:
      try:
        nd = next(sources[-1])
        if isinstance(nd, Tree):
          sources.append(iter(nd.children))
        else:
          yield nd
      except StopIteration:
        sources.pop()

class Children(View):

  def __iter__(self):
    for nd in self.source:
      for child in nd.children:
        yield child

class Attributes(View):

  def __iter__(self):
    for nd in self.source:
      for a in nd.attrs:
        yield a

class Values(View):

  def __iter__(self):
    for name, value in self.source:
      yield value

def flatten_path(path):
  if isinstance(path, STRING_TYPES):
    for part in path.split("/"):
      yield part
  elif callable(path):
    yield path
  else:
    for p in path:
      for fp in flatten_path(p):
        yield fp

class Query(View):

  def __iter__(self):
    for nd in self.source:
      yield nd

  def __getitem__(self, path):
    query = self.source
    for p in flatten_path(path):
      if callable(p):
        select = Query
        pred = p
        source = query
      elif isinstance(p, STRING_TYPES):
        if p[0] == "@":
          select = Values
          pred = lambda x, n=p[1:]: x[0] == n
          source = Attributes(query)
        elif p[0] == "#":
          select = Query
          pred = lambda x, t=p[1:]: x.is_type(t)
          source = Children(query)
        else:
          select = Query
          pred = lambda x, n=p: isinstance(x, Tag) and x.name == n
          source = Flatten(Children(query))
      else:
        raise ValueError(p)
      query = select(Filter(pred, source))

    return query
