import socket
import RawFileClient
import ContainerClient

from Ft.Server.Common import ResourceTypes

from Ft.Server.FtRpc import Commands

class RepositoryClient(ContainerClient.ContainerClient):
    """
    Implementation for a repository instance
    """
    def __init__(self, connection):
        self._completed = 0
        ContainerClient.ContainerClient.__init__(
            self, '/', connection,
            ResourceTypes.ResourceType.CONTAINER, self)
        return

    def reloadModule(self, module):
        """
        Reload a Python module
        """
        Commands.RemoteMethodCommand('reloadModule',
                                     self._path,
                                     (module,)
                                     ).send(self._connection).results

    #####################################
    # XSLT Strobe
    #####################################
    def addXsltStrobe(self, path):
        """
        Register an XSLT file to be run on the strobe signal
        """
        Commands.RemoteMethodCommand('addXsltStrobe',
                                     self._path,
                                     (path,)
                                     ).send(self._connection).results

    #####################################
    #Text Indexing and Searching interfaces
    #####################################
    def purgeTemporaryResources(self):
        """
        Remove from the repository all temporary resources that have
        outlived their lifetimes
        """
        Commands.RemoteMethodCommand('purgeTemporaryResources',
                                     self._path,
                                     ()
                                    ).send(self._connection).results


    def searchDocuments(self, searchString):
        """
        Returns the paths to all metadocuments (whose document
        definitions specify that they are to be text indexed) that
        match the specified Swish query string
        """
        return Commands.RemoteMethodCommand('searchDocuments',
                                            self._path,
                                            (searchString,)
                                            ).send(self._connection).results

    def reindex(self):
        """
        Performs a text-reindex on all metadocuments whose document
        definiton specifies a full text index
        """
        return Commands.RemoteMethodCommand('reindex',
                                            self._path,
                                            ()
                                            ).send(self._connection).results

    ##############################################
    #Session Interfaces
    ##############################################
    #
    ## do not define checkLogin()!

    def createSession(self, key=None, ttl=0):
        """
        Create a new session from this connection.
        If key is specified, then the session ID is generated from
        this key, and whenever the session is accessed, the key must be
        given or the session will be invalidated.

        ttl - session time to live, in seconds.
        If ttl is 0, the driver default is used (usually 15 minutes).
        """
        return Commands.RemoteMethodCommand('createSession',
                                            self._path,
                                            (key, ttl)
                                            ).send(self._connection).results

    def hasSession(self):
        """
        See if this connection is in a session
        """
        return Commands.RemoteMethodCommand('hasSession',
                                            self._path,
                                            ()
                                            ).send(self._connection).results

    def getSessionData(self, key):
        """
        Get Session Data
        """
        return Commands.RemoteMethodCommand('getSessionData',
                                            self._path,
                                            (key,)
                                            ).send(self._connection).results

    def setSessionData(self, key, value):
        """
        Set Session Data
        """
        Commands.RemoteMethodCommand('setSessionData',
                                     self._path,
                                     (key, value)
                                    ).send(self._connection).results

    def deleteSessionData(self, key):
        """
        Delete Session Data
        """
        Commands.RemoteMethodCommand('deleteSessionData',
                                     self._path,
                                     (key,)
                                    ).send(self._connection).results

    def getSessionExpiration(self):
        """
        Get The expiration time of this session
        """
        return Commands.RemoteMethodCommand('getSessionExpiration',
                                            self._path,
                                            ()
                                            ).send(self._connection).results

    def invalidateSession(self):
        """
        Invalidate this session.
        """
        Commands.RemoteMethodCommand('invalidateSession',
                                     self._path,
                                     ()
                                    ).send(self._connection).results

    ##############################################
    #Transaction Interfaces
    ##############################################
    def getUserName(self):
        return Commands.RemoteMethodCommand('getUserName',
                                            self._path,
                                            ()
                                            ).send(self._connection).results

    def getCurrentUser(self):
        userPath = Commands.RemoteMethodCommand('getCurrentUser',
                                                self._path,
                                                ()
                                                ).send(self._connection).results
        return self.fetchResource(userPath)

    def txCommit(self):
        """
        Commit the transaction associated w/ this repository instance
        """
        try:
            Commands.LogoutCommand(commit=1).send(self._connection)
        except socket.error:
            pass
        self._completed = 1
        self._cache = None
        self._connection = None


    def txRollback(self):
        """
        Rollback the transaction associated w/ this repository instance
        """
        try:
            Commands.LogoutCommand(commit=0).send(self._connection)
        except socket.error:
            pass
        self._completed = 1
        self._cache = None
        self._connection = None

    #######################################
    # Interfaces that span the repo
    #######################################
    def getAllGroupPaths(self):
        """
        Get a list of Paths for all of the groups in the system
        """
        return Commands.RemoteMethodCommand('getAllGroupPaths',
                                            self._path,
                                            ()
                                            ).send(self._connection).results

    def getAllUserPaths(self):
        """
        Get a list of Paths for all of the users in the system
        """
        return Commands.RemoteMethodCommand('getAllUserPaths',
                                            self._path,
                                            ()
                                            ).send(self._connection).results

    def getAllGroupNames(self):
        """
        Get a list of group names for all of the users in the system
        """
        return Commands.RemoteMethodCommand('getAllGroupNames',
                                            self._path,
                                            ()
                                            ).send(self._connection).results


    def getAllUserNames(self):
        """
        Get a list of user names for all of the users in the system
        """
        return Commands.RemoteMethodCommand('getAllUserNames',
                                            self._path,
                                            ()
                                            ).send(self._connection).results

    def fetchUserOrGroupByName(self, name):
        """
        Fetch a user or a group by name (not full path)
        """

        path = Commands.RemoteMethodCommand('fetchUserOrGroupByName',
                                            self._path,
                                            (name,)
                                            ).send(self._connection).results
        if path is None:
            return path
        return self.fetchResource(path)

    def getAllDocumentDefinitionPaths(self):
        """
        Get a list of Paths for all of the document definitions in the system
        """
        return Commands.RemoteMethodCommand('getAllDocumentDefinitionPaths',
                                            self._path,
                                            ()
                                            ).send(self._connection).results

    def getCommand(self,cmdName):
        """
        Get a command object by its name.
        The name should be dot-separated, like 4ss_manager.init
        """
        rt = Commands.RemoteMethodCommand('getCommand',
                                          self._path,
                                          (cmdName,)
                                          ).send(self._connection).results
        if rt is None:
            return rt
        return self.fetchResource(rt)
