# -*- coding: iso-8859-1 -*-
#
# Copyright (C) 2005 Edgewall Software
# Copyright (C) 2005,2006 Lele Gaifax <lele@metapensiero.it>
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://trac.edgewall.com/license.html.
#
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://projects.edgewall.com/trac/.
#
# Author: Lele Gaifax <lele@metapensiero.it>

from mimetypes import guess_type
from os.path import split
from trac.versioncontrol import Changeset, Node

class DarcsNode(Node):
    """
    Represent a single item changed within a Changeset.
    """

    def __init__(self, path, rev, kind, change, repository,
                 ancestor_path=None, ancestor_rev=None):
        Node.__init__(self, path, rev, kind)
        self.change = change
        self.repository = repository
        self.ancestor_path = ancestor_path
        self.ancestor_rev = ancestor_rev
        # The following two ivars are required by the changeset module
        self.created_path = path
        self.created_rev = rev

    def __cmp__(self, other):
        res = cmp(self.rev, other.rev)
        if res:
            return res
        res = cmp(self.path, other.path)
        if res == 0:
            if self.change==Changeset.MOVE and other.change==Changeset.DELETE:
                res = 1
            elif self.change==Changeset.DELETE and other.change==Changeset.MOVE:
                res = -1
        return res

    def get_content(self):
        """
        Return a stream for reading the content of the node. This method
        will return None for directories. The returned object should provide
        a read([len]) function.
        """

        if self.isdir:
            return None

        return self.repository._getNodeContent(self)

    def get_entries(self):
        """
        Generator that yields the immediate child entries of a directory, in no
        particular order. If the node is a file, this method returns None.
        """

        if self.isdir:
            return self.repository._getNodeEntries(self)

    def get_history(self, limit=None):
        """
        Generator that yields (path, rev, chg) tuples, one for each
        revision in which the node was changed. This generator will
        follow copies and moves of a node (if the underlying version
        control system supports that), which will be indicated by the
        first element of the tuple (i.e. the path) changing.
        """

        # Start with current version
        yield (self.path, self.rev, self.change)

        # Keep going with the previous steps, possibly following the old
        # name of the entry if this is a move.
        prevpath = self.ancestor_path
        prevrev = self.ancestor_rev
        if limit is not None:
            limit -= 1
        prevhist = self.repository.get_path_history(prevpath, prevrev)
        for path, rev, chg in prevhist:
            yield (path, rev, chg)

    def get_properties(self):
        """
        Returns a dictionary containing the properties (meta-data) of the node.
        The set of properties depends on the version control system.
        """

        return {}

    def get_content_length(self):
        if self.isdir:
            return None
        return self.repository._getNodeSize(self)

    def get_content_type(self):
        if self.isdir:
            return None
        return guess_type(self.path)[0]

    def get_name(self):
        return split(self.path)[1]

    def get_last_modified(self):
        return self.repository._getNodeLastModified(self)
