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

from __future__ import division, with_statement

import datetime
import logging
import re
import sqlite3
import unicodedata


class Error(Exception):
    def __init__(self, msg, *args, **kwargs):
        action = kwargs.pop("action", None)
        if action is not None:
            msg = "%s %s" % (NodeRev._opname(action), msg)
        super(Error, self).__init__(msg, *args, **kwargs)


class SQLclass(object):
    """Named index of SQL schema definitions and statements.

    Parses "schema.sql" and creates a class-level attribute for each
    script and statement in that file.
    """

    def __init__(self):
        import cStringIO
        import pkgutil
        import re

        comment_rx = re.compile(r"\s*--.*$")
        header_rx = re.compile(r"^---(?P<kind>STATEMENT|SCRIPT)"
                               r"\s+(?P<name>[_A-Z]+)$")

        kind = None
        name = None
        content = None

        def record_current_statement():
            if name is not None:
                if kind == "SCRIPT":
                    self.__record_script(name, content.getvalue())
                else:
                    self.__record_statement(name, content.getvalue())

        schema = cStringIO.StringIO(pkgutil.get_data(__name__, "schema.sql"))
        for line in schema:
            line = line.rstrip()
            if not line:
                continue

            header = header_rx.match(line)
            if header:
                record_current_statement()
                kind = header.group("kind")
                name = header.group("name")
                content = cStringIO.StringIO()
                continue

            line = comment_rx.sub("", line)
            if not line:
                continue

            if content is not None:
                content.write(line)
                content.write("\n")
        record_current_statement()

    class __statement(object):
        __slots__ = ("execute", "query")
        def __init__(self, sql, query):
            self.execute = sql._execute
            self.query = query

        def __call__(self, cursor, **kwargs):
            if len(kwargs):
                return self.execute(cursor, self.query, kwargs)
            return self.execute(cursor, self.query)

    def __record_statement(self, name, statement):
        setattr(self, name, self.__statement(self, statement))

    class __script(object):
        __slots__ = ("execute", "query")
        def __init__(self, sql, query):
            self.execute = sql._executescript
            self.query = query

        def __call__(self, cursor):
            return self.execute(cursor, self.query)

    def __record_script(self, name, script):
        setattr(self, name, self.__script(self, script))

    LOGLEVEL = (logging.NOTSET + logging.DEBUG) // 2
    if logging.getLevelName(LOGLEVEL) == 'Level %s' % LOGLEVEL:
        logging.addLevelName(LOGLEVEL, 'SQL')

    def _log(self, *args, **kwargs):
        return logging.log(self.LOGLEVEL, *args, **kwargs)

    __stmt_param_rx = re.compile(r':([a-z]+)')
    def _execute(self, cursor, statement, parameters=None):
        if parameters is not None:
            fmt = statement.replace("%", "%%")
            fmt = self.__stmt_param_rx.sub(r'%(\1)r', fmt)
            self._log("EXECUTE: " + fmt, parameters)
            return cursor.execute(statement, parameters)
        else:
            self._log("EXECUTE: %s", statement)
            return cursor.execute(statement)

    def _executescript(self, cursor, script):
        self._log("EXECUTE: %s", script)
        return cursor.executescript(script)
SQL = SQLclass()


class SQLobject(dict):
    """Base for ORM abstractions."""

    def __init__(self, **kwargs):
        super(SQLobject, self).__init__(**kwargs)
        for name in self._columns:
            super(SQLobject, self).setdefault(name, None)

    def __getattr__(self, name):
        return self.__getitem__(name)

    def __setattr__(self, name, value):
        return self.__setitem__(name, value)

    def __delattr__(self, name):
        return self.__delitem__(name)

    def _put(self, _cursor):
        self._put_statement(_cursor, **self)
        if self.id is None:
            self.id = _cursor.lastrowid
        else:
            assert self.id == _cursor.lastrowid

    @classmethod
    def _get(self, _cursor, pkey):
        self._get_statement(_cursor, id=pkey)
        return cls._from_row(_cursor.fetchone())

    @classmethod
    def _from_row(cls, row):
        if row is not None:
            return cls(**row)
        return None

    def _clone(self):
        return self.__class__(**self)


class Txn(SQLobject):
    """O/R mapping for the "txn" table."""

    _columns = ("id", "treeid", "revision", "created", "author", "state")
    _put_statement = SQL.TXN_INSERT
    _get_statement = SQL.TXN_GET

    # state
    TRANSIENT = "T"
    PERMANENT = "P"
    DEAD = "D"

    def __init__(self, **kwargs):
        super(Txn, self).__init__(**kwargs)
        if self.state is None:
            self.state = self.TRANSIENT

    def __str__(self):
        return "%d/%d %c %s" % (self.revision, self.treeid,
                                self.state, self.created)

    @property
    def _committed(self):
        return self.state == self.PERMANENT

    @property
    def _uncommitted(self):
        return self.state == self.TRANSIENT

    @property
    def _dead(self):
        return self.state == self.DEAD

    @staticmethod
    def _now():
        now = datetime.datetime.utcnow()
        return (now.strftime("%Y%m%dT%H%M%S.%%03dZ")
                % ((now.microsecond + 500) // 1000))

    def _put(self, cursor):
        if self.created is None:
            self.created = self._now()
        super(Txn, self)._put(cursor)
        if self.treeid is None:
            SQL.TXN_UPDATE_INITIAL_TREEID(cursor, id = self.id)
            self.treeid = self.id

    @classmethod
    def _find_newest(cls, cursor):
        SQL.TXN_FIND_NEWEST(cursor)
        return cls._from_row(cursor.fetchone())

    @classmethod
    def _find_by_revision(cls, cursor, revision):
        SQL.TXN_FIND_BY_REVISION(cursor, revision = revision)
        return cls._from_row(cursor.fetchone())

    @classmethod
    def _find_by_revision_timestamp(cls, cursor, revision, created):
        SQL.TXN_FIND_BY_REVISION_AND_TIMESTAMP(
            cursor, revision = revision, created = creted)
        return cls._from_row(cursor.fetchone())

    def _commit(self, cursor, revision):
        assert self._uncommitted
        now = self._now()
        SQL.TXN_COMMIT(cursor, id = self.id,
                       revision = revision, created = now)
        self.revision = revision
        self.created = now
        self.state = self.PERMANENT

    def _abort(self, cursor):
        assert self._uncommitted
        SQL.TXN_ABORT(cursor, id = self.id)
        self.state = self.DEAD

    def _cleanup(self, cursor):
        assert self._dead
        SQL.TXN_CLEANUP(cursor, id = self.id)


class Branch(SQLobject):
    """O/R mapping for the "branch" table."""

    _columns = ("id", "treeid", "nodeid", "origin", "state")
    _put_statement = SQL.BRANCH_INSERT
    _get_statement = SQL.BRANCH_GET

    # state
    TRANSIENT = "T"
    PERMANENT = "P"

    def __init__(self, **kwargs):
        super(Branch, self).__init__(**kwargs)
        if self.state is None:
            self.state = self.TRANSIENT

    def _put(self, cursor):
        super(Branch, self)._put(cursor)
        if self.nodeid is None:
            SQL.BRANCH_UPDATE_INITIAL_NODEID(cursor, id = self.id)
            self.nodeid = self.id

    @classmethod
    def _update_treeid(cls, cursor, new_txn, old_txn):
        SQL.BRANCH_UPDATE_TREEID(cursor,
                                 new_treeid = new_txn.treeid,
                                 old_treeid = old_txn.treeid)

    @classmethod
    def _history(cls, cursor, nodeid):
        SQL.BRANCH_HISTORY(cursor, nodeid = nodeid)
        for row in cursor:
            yield cls._from_row(row)

    @classmethod
    def _commit(cls, cursor, txn):
        SQL.BRANCH_COMMIT(cursor, treeid = txn.treeid)

    @classmethod
    def _cleanup(cls, cursor, txn):
        SQL.BRANCH_CLEANUP(cursor, treeid = txn.treeid)


class NodeRev(SQLobject):
    """O/R mapping for the noderev/string/nodeview table."""

    _columns = ("id", "treeid", "nodeid", "origin", "parent", "branch",
                "nameid", "name", "denameid", "dename",
                "kind", "opcode", "state")
    _put_statement = SQL.NODEREV_INSERT
    _get_statement = SQL.NODEVIEW_GET

    # kind
    DIR = "D"
    FILE = "F"

    # opcode
    ADD = "A"
    REPLACE = "R"
    MODIFY = "M"
    DELETE = "D"
    RENAME = "N"
    BRANCH = "B"
    LAZY = "L"
    BREPLACE = "X"
    LAZY_BREPLACE = "Z"

    # state
    TRANSIENT = "T"
    PERMANENT = "P"

    def __init__(self, **kwargs):
        super(NodeRev, self).__init__(**kwargs)
        if self.state is None:
            self.state = self.TRANSIENT

    def __str__(self):
        return "%d %c %s%s" % (self.treeid, self.opcode, self.name,
                               self._isdir and '/' or '')

    # Opcode names
    __opnames = {ADD: "add",
                 REPLACE: "replace",
                 MODIFY: "modify",
                 DELETE: "delete",
                 RENAME: "rename",
                 BRANCH: "branch",
                 LAZY: "branch",
                 BREPLACE: "branch/replace",
                 LAZY_BREPLACE: "branch/replace"}

    @classmethod
    def _opname(cls, change):
        return cls.__opnames.get(opcode)

    @property
    def _deleted(self):
        return (self.opcode == self.DELETE)

    @property
    def _lazy(self):
        return (self.opcode in (self.LAZY, self.LAZY_BREPLACE))

    @property
    def _transient(self):
        return (self.state == self.TRANSIENT)

    @property
    def _isdir(self):
        return (self.kind == self.DIR)

    @staticmethod
    def __stringid(cursor, val):
        SQL.STRING_FIND(cursor, val = val)
        row = cursor.fetchone()
        if row is not None:
            return row['id']
        SQL.STRING_INSERT(cursor, val = val)
        return cursor.lastrowid

    def _put(self, cursor):
        if self.nameid is None:
            assert self.name is not None
            self.nameid = self.__stringid(cursor, self.name)
        if self.denameid is None:
            if self.dename == self.name:
                self.denameid = self.nameid
            else:
                assert self.dename is not None
                self.denameid = self.__stringid(cursor, self.dename)
        super(NodeRev, self)._put(cursor)

    @classmethod
    def _update_treeid(cls, cursor, new_txn, old_txn):
        SQL.NODEREV_UPDATE_TREEID(cursor,
                                  new_treeid = new_txn.treeid,
                                  old_treeid = old_txn.treeid)

    def _delazify(self, cursor):
        assert self._lazy and self._isdir
        opcode = self.opcode == self.LAZY and self.BRANCH or self.BREPLACE
        SQL.NODEREV_UPDATE_OPCODE(cursor, id = self.id, opcode = opcode)
        self.opcode = opcode

    @classmethod
    def _commit(cls, cursor, txn):
        SQL.NODEREV_COMMIT(cursor, treeid = txn.treeid)

    @classmethod
    def _cleanup(cls, cursor, txn):
        SQL.NODEREV_CLEANUP(cursor, treeid = txn.treeid)

    @classmethod
    def __find(cls, cursor, parent, name, txn):
        if txn.state != txn.PERMANENT:
            if parent is None:
                finder = SQL.NODEVIEW_FIND_TRANSIENT_ROOT
            else:
                finder = SQL.NODEVIEW_FIND_TRANSIENT_BY_NAME
        else:
            if parent is None:
                finder = SQL.NODEVIEW_FIND_ROOT
            else:
                finder = SQL.NODEVIEW_FIND_BY_NAME
        finder(cursor, name = name, parent = parent, treeid = txn.treeid)
        return cls._from_row(cursor.fetchone())

    @classmethod
    def _find(cls, cursor, parent, name, txn):
        return cls.__find(cursor, parent, cls.__normtext(name), txn)

    @classmethod
    def _commonprefix(cls, *args):
        args = [arg.split('/') for arg in args]
        prefix = []
        arglen = min(len(parts) for parts in args)
        while arglen > 0:
            same = set(cls.__normtext(parts[0]) for parts in args)
            if len(same) > 1:
                break
            for parts in args:
                del parts[0]
            prefix.append(same.pop())
            arglen -= 1
        return '/'.join(prefix), ['/'.join(parts) for parts in args]

    @classmethod
    def _lookup(cls, cursor, track, relpath, txn):
        if track is None or track.path is None:
            # Lookup from root
            track = Track()
            parent = cls.__find(cursor, None, "", txn)
            if not relpath:
                track.close(parent)
                return track
            track.append(parent)
        else:
            assert track.found
            track = Track(track)
            if not relpath:
                track.close()
                return track
            parent = track.noderev
        parts = cls.__normtext(relpath).split("/")
        for name in parts[:-1]:
            if not parent._isdir:
                raise Error("ENOTDIR: " + track.path)
            while parent._lazy:
                parent = cls._get(cursor, id = parent.origin)
            node = cls.__find(cursor, parent.branch, name, txn)
            if node is None:
                raise Error("ENODIR: " +  track.path + '/' + name)
            parent = node
            track.append(parent)
        while parent._lazy:
            parent = cls._get(cursor, id = parent.origin)
        track.close(cls.__find(cursor, parent.branch, parts[-1], txn))
        return track

    def _count_successors(self, cursor):
        SQL.NODEREV_COUNT_SUCCESSORS(cursor, origin = self.id)
        return int(cursor.fetchone()[0])

    def _listdir(self, cursor, txn):
        assert self._isdir
        if txn.state != txn.PERMANENT:
            lister = SQL.NODEVIEW_LIST_TRANSIENT_DIRECTORY
        else:
            lister = SQL.NODEVIEW_LIST_DIRECTORY
        lister(cursor, parent = self.id, treeid = txn.treeid)
        for row in cursor:
            yield self._from_row(row)

    def _bubbledown(self, cursor, txn):
        assert txn._uncommitted
        assert self._lazy and self._isdir and self.origin is not None
        originmap = dict()
        origin = self
        while origin._lazy:
            origin = self._get(cursor, id = origin.origin)
        for node in origin._listdir(cursor, txn):
            newnode = node._branch(cursor, self, txn)
            originmap[newnode.origin] == newnode
        self._delazify(cursor)
        return originmap

    def _branch(self, cursor, parent, txn, replaced=False):
        assert txn._uncommitted
        branch = Branch(treeid = txn.treeid,
                        nodeid = self.nodeid,
                        origin = self.branch)
        branch._put(cursor)
        if self._isdir:
            opcode = replaced and self.LAZY_BREPLACE or self.LAZY
        else:
            opcode = replaced and self.BREPLACE or self.BRANCH
        node = self._revise(opcode, txn)
        node.parent = parent.id
        node.branch = branch.id
        node._put(cursor)
        return node

    def _revise(self, opcode, txn):
        assert txn._uncommitted
        noderev = NodeRev._clone(self)
        noderev.treeid = txn.treeid
        noderev.opcode = opcode

    __readonly = frozenset(("name",))
    def __setitem__(self, key, value):
        if key in self.__readonly:
            raise Error("NodeRev.%s is read-only" % key)
        if key == "dename":
            name = self.__normtext(value)
            value = self.__text(value)
            super(NodeRev, self).__setitem__("name", name)
        super(NodeRev, self).__setitem__(key, value)

    def __getitem__(self, key):
        if key == "dename":
            dename = super(NodeRev, self).__getitem__(key)
            if dename is not None:
                return dename
            key = "name"
        return super(NodeRev, self).__getitem__(key)

    @classmethod
    def __text(cls, name):
        if not isinstance(name, unicode):
            return name.decode("UTF-8")
        return name

    @classmethod
    def __normtext(cls, name):
        return unicodedata.normalize('NFC', cls.__text(name))


class Track(object):
    __slots__ = ("nodelist", "noderev", "lazy")
    def __init__(self, other=None):
        if other is None:
            self.nodelist = list()
            self.noderev = None
            self.lazy = None
        else:
            self.nodelist = list(other.nodelist)
            self.noderev = other.noderev
            self.lazy = other.lazy

    def __str__(self):
        return "%c%c %r" % (
            self.found and self.noderev.kind or '-',
            self.lazy is not None and 'L' or '-',
            self.path)

    @property
    def found(self):
        return (self.noderev is not None)

    @property
    def parent(self):
        if self.noderev is not None:
            index = len(self.nodelist) - 2;
        else:
            index = len(self.nodelist) - 1;
        if index >= 0:
            return self.nodelist[index]
        return None

    @property
    def path(self):
        if len(self.nodelist):
            return '/'.join(n.name for n in self.nodelist[1:])
        return None

    @property
    def open(self):
        return not isinstance(self.nodelust, tuple)

    def append(self, noderev):
        if self.lazy is None and noderev._lazy:
            self.lazy = len(self.nodelist)
        self.nodelist.append(noderev)

    def close(self, noderev=None):
        if noderev is not None:
            self.append(noderev)
            self.noderev = noderev
        self.nodelist = tuple(self.nodelist)

    def bubbledown(self, cursor, txn):
        if self.lazy is None:
            return
        closed = not self.open
        if closed:
            self.nodelist = list(self.nodelist)
        tracklen = len(self.nodelist)
        index = self.lazy
        node = self.nodelist[index]
        originmap = node._bubbledown(cursor, txn)
        while index < tracklen:
            node = originmap[self.nodelist[index].id]
            self.nodelist[index] = node
            if node._isdir:
                originmap = node._bubbledown(cursor, txn)
            else:
                originmap = None
            index += 1
        self.lazy = None
        if closed:
            self.close()


class Index(object):
    def __init__(self, database):
        self.conn = sqlite3.connect(database, isolation_level = "DEFERRED")
        self.conn.row_factory = sqlite3.Row
        self.cursor = self.conn.cursor()
        self.cursor.execute("PRAGMA page_size = 4096")
        self.cursor.execute("PRAGMA temp_store = MEMORY")
        self.cursor.execute("PRAGMA foreign_keys = ON")
        self.cursor.execute("PRAGMA case_sensitive_like = ON")
        self.cursor.execute("PRAGMA encoding = 'UTF-8'")

    def initialize(self):
        try:
            SQL.CREATE_SCHEMA(self.cursor)
            SQL._execute(
                self.cursor,
                "UPDATE txn SET created = :created WHERE id = 0",
                {"created": Txn._now()})
            self.commit()
        except:
            self.rollback()
            raise

    def begin(self):
        SQL._execute(self.cursor, "BEGIN")

    def commit(self):
        SQL._log("COMMIT")
        self.conn.commit()

    def rollback(self):
        SQL._log("ROLLBACK")
        self.conn.rollback()

    def close(self):
        self.rollback()
        SQL._log("CLOSE")
        self.conn.close()

    def get_txn(self, revision=None):
        if revision is None:
            return Txn._find_newest(self.cursor)
        return Txn._find_by_revision(self.cursor, revision)

    def new_txn(self, revision, created=None, author=None, base_txn = None):
        assert base_txn is None or base_txn.revision == revision
        txn = Txn(revision = revision, created = created, author = author,
                  treeid = base_txn is not None and base_txn.treeid or None)
        txn._put(self.cursor)
        return txn

    def commit_txn(self, txn, revision):
        txn._commit(self.cursor, revision)
        NodeRev._commit(self.cursor, txn)
        Branch._commit(self.cursor, txn)

    def abort_txn(self, txn):
        txn._abort(self.cursor)
        NodeRev._cleanup(self.cursor, txn)
        Branch._cleanup(self.cursor, txn)
        txn._cleanup(self.cursor)

    def listdir(self, txn, noderev):
        # FIXME: Query seems OK but no results returned?
        return noderev._listdir(self.conn.cursor(), txn)

    def lookup(self, txn, track=None, relpath=""):
        return NodeRev._lookup(self.cursor, track, relpath, txn)

    def __add(self, txn, track, name, kind, opcode, origintrack=None):
        assert kind in (NodeRev.FILE, NodeRev.DIR)
        assert opcode in (NodeRev.ADD, NodeRev.REPLACE)
        if not txn._uncommitted:
            raise Error("EREADONLY: txn " + str(txn))
        if not track.found:
            raise Error("ENOENT: " +  track.path)
        if not track.noderev._isdir:
            raise Error("ENOTDIR: " +  track.path)

        parent = track.noderev
        oldnode = NodeRev._find(self.cursor, parent.id, name, txn)
        if opcode == NodeRev.ADD and oldnode is not None:
            raise Error("EEXIST: " +  track.path + '/' + name)

        if origintrack is not None:
            # Treat add as copy
            if not origintrack.found:
                raise Error("ENOENT: (origin) " +  origintrack.path)
            origin = origintrack.noderev
            if origin.kind != kind:
                raise Error("ENOTSAME: origin %c -> copy %c"
                            % (origin.kind, kind))
            ### Rename detection heuristics here ...
            rename = False
        else:
            origin = None
            rename = False

        if rename:
            raise NotImplementedError("Rename detection heuristics")

        track = Track(track)
        track.bubbledown(self.cursor, txn)
        if oldnode:
            if parent.id != track.noderev.id:
                # Bubbledown changed the track
                parent = track.noderev
                oldnode = NodeRev._find(self.cursor, parent.id, name, txn)
                assert oldnode is not None
            tombstone = oldnode._revise(oldnode.DELETE, txn)
            tombstone.parent = parent.id
            tombstone._put(self.cursor)
        parent = track.noderev
        if origin is not None:
            newnode = origin._branch(self.cursor, parent.id, txn,
                                     replaced = (oldnode is not None))
        else:
            branch = Branch(treeid = txn.treeid)
            branch._put(self.cursor)
            newnode = NodeRev(treeid = txn.treeid,
                              nodeid = branch.nodeid,
                              branch = branch.id,
                              parent = parent.id,
                              kind = kind,
                              opcode = opcode)
            newnode.dename = name
            newnode._put(self.cursor)
        track.close(newnode)
        return track

    def add(self, txn, track, name, kind, origintrack=None):
        return self.__add(txn, track, name, kind, NodeRev.ADD, origintrack)

    def replace(self, txn, track, name, kind, origintrack=None):
        return self.__add(txn, track, name, kind, NodeRev.REPLACE, origintrack)

#    def modify(self, txn, track):
#        if not txn._uncommitted
#            raise Error("EREADONLY: txn " + str(txn))
#        if not track.found:
#            raise Error("ENOENT: " +  track.path)



class Tree(object):
    def __init__(self, index):
        self.index = index
        self.context = None
        index.rollback()


def simpletest(database):
    ix = Index(database)
    ix.initialize()

    try:
        print "Lookup root"
        tx = ix.get_txn()
        print "transaction:", tx
        root = ix.lookup(tx)
        print "root track:", root
        print "root noderev", root.noderev

        print "Add A/foo"
        tx = ix.new_txn(0)
        print "transaction:", tx
        parent = ix.add(tx, root, "A", NodeRev.DIR)
        print "A track:", parent
        print "A noderev", parent.noderev

        node = ix.add(tx, parent, "foo", NodeRev.FILE)
        print "foo track:", node
        print "foo noderev", node.noderev
        ix.commit_txn(tx, 1)
        ix.commit()

        print "List contents"
        tx = ix.get_txn()
        print "transaction:", tx
        root = ix.lookup(tx)
        print str(root.noderev)
        for n1 in ix.listdir(tx, root.noderev):
            print " ", str(n1)
            if n1._isdir:
                for n2 in ix.listdir(tx, n1):
                    print "   ", str(n2)

        print "Lookup A"
        track = ix.lookup(tx, None, "A")
        print str(track.noderev)

        print "Lookup A/foo"
        track = ix.lookup(tx, None, "A/foo")
        print str(track.noderev)
    finally:
        ix.close()

def loggedsimpletest(database):
    import sys
    logging.basicConfig(level=SQL.LOGLEVEL,
                        stream=sys.stderr)
    simpletest(database)
