# Copyright 2017-present Open Networking Foundation and others
#
# Licensed 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.

from __future__ import print_function
from six.moves import range


class LexHelper:
    offset = 0

    def get_max_linespan(self, p):
        defSpan = [1e60, -1]
        mSpan = [1e60, -1]
        for sp in range(0, len(p)):
            csp = p.linespan(sp)
            if csp[0] == 0 and csp[1] == 0:
                if hasattr(p[sp], "linespan"):
                    csp = p[sp].linespan
                else:
                    continue
            if csp is None or len(csp) != 2:
                continue
            if csp[0] == 0 and csp[1] == 0:
                continue
            if csp[0] < mSpan[0]:
                mSpan[0] = csp[0]
            if csp[1] > mSpan[1]:
                mSpan[1] = csp[1]
        if defSpan == mSpan:
            return (0, 0)
        return tuple([mSpan[0] - self.offset, mSpan[1] - self.offset])

    def get_max_lexspan(self, p):
        defSpan = [1e60, -1]
        mSpan = [1e60, -1]
        for sp in range(0, len(p)):
            csp = p.lexspan(sp)
            if csp[0] == 0 and csp[1] == 0:
                if hasattr(p[sp], "lexspan"):
                    csp = p[sp].lexspan
                else:
                    continue
            if csp is None or len(csp) != 2:
                continue
            if csp[0] == 0 and csp[1] == 0:
                continue
            if csp[0] < mSpan[0]:
                mSpan[0] = csp[0]
            if csp[1] > mSpan[1]:
                mSpan[1] = csp[1]
        if defSpan == mSpan:
            return (0, 0)
        return tuple([mSpan[0] - self.offset, mSpan[1] - self.offset])

    def set_parse_object(self, dst, p):
        dst.setLexData(
            linespan=self.get_max_linespan(p),
            lexspan=self.get_max_lexspan(p))
        dst.setLexObj(p)


class Base(object):
    parent = None
    lexspan = None
    linespan = None

    def v(self, obj, visitor):
        if obj is None:
            return
        elif hasattr(obj, "accept"):
            obj.accept(visitor)
        elif isinstance(obj, list):
            for s in obj:
                self.v(s, visitor)
            pass
        pass

    @staticmethod
    def p(obj, parent):
        if isinstance(obj, list):
            for s in obj:
                Base.p(s, parent)

        if hasattr(obj, "parent"):
            obj.parent = parent

# Lexical unit - contains lexspan and linespan for later analysis.


class LU(Base):

    def __init__(self, p, idx):
        self.p = p
        self.idx = idx
        self.pval = p[idx]
        self.lexspan = p.lexspan(idx)
        self.linespan = p.linespan(idx)

        # If string is in the value (raw value) and start and stop lexspan is the same, add real span
        # obtained by string length.
        if isinstance(self.pval, str) \
                and self.lexspan is not None \
                and self.lexspan[0] == self.lexspan[1] \
                and self.lexspan[0] != 0:
            self.lexspan = tuple(
                [self.lexspan[0], self.lexspan[0] + len(self.pval)])
        super(LU, self).__init__()

    @staticmethod
    def i(p, idx):
        if isinstance(p[idx], LU):
            return p[idx]
        if isinstance(p[idx], str):
            return LU(p, idx)
        return p[idx]

    def describe(self):
        return "LU(%s,%s)" % (self.pval, self.lexspan)

    def __str__(self):
        return self.pval

    def __repr__(self):
        return self.describe()

    def accept(self, visitor):
        self.v(self.pval, visitor)

    def __iter__(self):
        for x in self.pval:
            yield x

# Base node


class SourceElement(Base):
    '''
    A SourceElement is the base class for all elements that occur in a Protocol Buffers
    file parsed by plyproto.
    '''

    def __init__(self, linespan=[], lexspan=[], p=None):
        super(SourceElement, self).__init__()
        self._fields = []  # ['linespan', 'lexspan']
        self.linespan = linespan
        self.lexspan = lexspan
        self.p = p

    def __repr__(self):
        equals = ("{0}={1!r}".format(k, getattr(self, k))
                  for k in self._fields)
        args = ", ".join(equals)
        return "{0}({1})".format(self.__class__.__name__, args)

    def __eq__(self, other):
        try:
            return self.__dict__ == other.__dict__
        except AttributeError:
            return False

    def __ne__(self, other):
        return not self == other

    def setLexData(self, linespan, lexspan):
        self.linespan = linespan
        self.lexspan = lexspan

    def setLexObj(self, p):
        self.p = p

    def accept(self, visitor):
        pass


class Visitor(object):

    def __init__(self, verbose=False):
        self.verbose = verbose

    def __getattr__(self, name):
        if not name.startswith('visit_'):
            raise AttributeError(
                'name must start with visit_ but was {}'.format(name))

        def f(element):
            if self.verbose:
                msg = 'unimplemented call to {}; ignoring ({})'
                print((msg.format(name, element)))
            return True
        return f

    # visitor.visit_PackageStatement(self)
    # visitor.visit_ImportStatement(self)
    # visitor.visit_OptionStatement(self)
    # visitor.visit_FieldDirective(self)
    # visitor.visit_FieldType(self)
    # visitor.visit_FieldDefinition(self)
    # visitor.visit_EnumFieldDefinition(self)
    # visitor.visit_EnumDefinition(self)
    # visitor.visit_MessageDefinition(self)
    # visitor.visit_MessageExtension(self)
    # visitor.visit_MethodDefinition(self)
    # visitor.visit_ServiceDefinition(self)
    # visitor.visit_ExtensionsDirective(self)
    # visitor.visit_Literal(self)
    # visitor.visit_Name(self)
    # visitor.visit_Proto(self)
    # visitor.visit_LU(self)
