#! /usr/bin/env python

"""Remote CVS -- command line interface"""

# XXX To do:
#
# Bugs:
# - if the remote file is deleted, "rcvs update" will fail
#
# Functionality:
# - cvs rm
# - descend into directories (alraedy done for update)
# - conflict resolution
# - other relevant commands?
# - branches
#
# - Finesses:
# - retain file mode's x bits
# - complain when "nothing known about filename"
# - edit log message the way CVS lets you edit it
# - cvs diff -rREVA -rREVB
# - send mail the way CVS sends it
#
# Performance:
# - cache remote checksums (for every revision ever seen!)
# - translate symbolic revisions to numeric revisions
#
# Reliability:
# - remote locking
#
# Security:
# - Authenticated RPC?


from cvslib import CVS, File
import md5
import os
import sys
from cmdfw import CommandFrameWork


DEF_LOCAL = 1                           # Default -l


class MyFile(File):

    def action(self):
        """Return a code indicating the update status of this file.

        The possible return values are:

        '=' -- everything's fine
        '0' -- file doesn't exist anywhere
        '?' -- exists locally only
        'A' -- new locally
        'R' -- deleted locally
        'U' -- changed remotely, no changes locally
               (includes new remotely or deleted remotely)
        'M' -- changed locally, no changes remotely
        'C' -- conflict: changed locally as well as remotely
               (includes cases where the file has been added
               or removed locally and remotely)
        'D' -- deleted remotely
        'N' -- new remotely
        'r' -- get rid of entry
        'c' -- create entry
        'u' -- update entry

        (and probably others :-)
        """
        if not self.lseen:
            self.getlocal()
        if not self.rseen:
            self.getremote()
        if not self.eseen:
            if not self.lsum:
                if not self.rsum: return '0' # Never heard of
                else:
                    return 'N' # New remotely
            else: # self.lsum
                if not self.rsum: return '?' # Local only
                # Local and remote, but no entry
                if self.lsum == self.rsum:
                    return 'c' # Restore entry only
                else: return 'C' # Real conflict
        else: # self.eseen
            if not self.lsum:
                if self.edeleted:
                    if self.rsum: return 'R' # Removed
                    else: return 'r' # Get rid of entry
                else: # not self.edeleted
                    if self.rsum:
                        print("warning:", end=' ')
                        print(self.file, end=' ')
                        print("was lost")
                        return 'U'
                    else: return 'r' # Get rid of entry
            else: # self.lsum
                if not self.rsum:
                    if self.enew: return 'A' # New locally
                    else: return 'D' # Deleted remotely
                else: # self.rsum
                    if self.enew:
                        if self.lsum == self.rsum:
                            return 'u'
                        else:
                            return 'C'
                    if self.lsum == self.esum:
                        if self.esum == self.rsum:
                            return '='
                        else:
                            return 'U'
                    elif self.esum == self.rsum:
                        return 'M'
                    elif self.lsum == self.rsum:
                        return 'u'
                    else:
                        return 'C'

    def update(self):
        code = self.action()
        if code == '=': return
        print(code, self.file)
        if code in ('U', 'N'):
            self.get()
        elif code == 'C':
            print("%s: conflict resolution not yet implemented" % \
                  self.file)
        elif code == 'D':
            remove(self.file)
            self.eseen = 0
        elif code == 'r':
            self.eseen = 0
        elif code in ('c', 'u'):
            self.eseen = 1
            self.erev = self.rrev
            self.enew = 0
            self.edeleted = 0
            self.esum = self.rsum
            self.emtime, self.ectime = os.stat(self.file)[-2:]
            self.extra = ''

    def commit(self, message = ""):
        code = self.action()
        if code in ('A', 'M'):
            self.put(message)
            return 1
        elif code == 'R':
            print("%s: committing removes not yet implemented" % \
                  self.file)
        elif code == 'C':
            print("%s: conflict resolution not yet implemented" % \
                  self.file)

    def diff(self, opts = []):
        self.action()           # To update lseen, rseen
        flags = ''
        rev = self.rrev
        # XXX should support two rev options too!
        for o, a in opts:
            if o == '-r':
                rev = a
            else:
                flags = flags + ' ' + o + a
        if rev == self.rrev and self.lsum == self.rsum:
            return
        flags = flags[1:]
        fn = self.file
        data = self.proxy.get((fn, rev))
        sum = md5.new(data).digest()
        if self.lsum == sum:
            return
        import tempfile
        tf = tempfile.NamedTemporaryFile()
        tf.write(data)
        tf.flush()
        print('diff %s -r%s %s' % (flags, rev, fn))
        sts = os.system('diff %s %s %s' % (flags, tf.name, fn))
        if sts:
            print('='*70)

    def commitcheck(self):
        return self.action() != 'C'

    def put(self, message = ""):
        print("Checking in", self.file, "...")
        data = open(self.file).read()
        if not self.enew:
            self.proxy.lock(self.file)
        messages = self.proxy.put(self.file, data, message)
        if messages:
            print(messages)
        self.setentry(self.proxy.head(self.file), self.lsum)

    def get(self):
        data = self.proxy.get(self.file)
        f = open(self.file, 'w')
        f.write(data)
        f.close()
        self.setentry(self.rrev, self.rsum)

    def log(self, otherflags):
        print(self.proxy.log(self.file, otherflags))

    def add(self):
        self.eseen = 0          # While we're hacking...
        self.esum = self.lsum
        self.emtime, self.ectime = 0, 0
        self.erev = ''
        self.enew = 1
        self.edeleted = 0
        self.eseen = 1          # Done
        self.extra = ''

    def setentry(self, erev, esum):
        self.eseen = 0          # While we're hacking...
        self.esum = esum
        self.emtime, self.ectime = os.stat(self.file)[-2:]
        self.erev = erev
        self.enew = 0
        self.edeleted = 0
        self.eseen = 1          # Done
        self.extra = ''


SENDMAIL = "/usr/lib/sendmail -t"
MAILFORM = """To: %s
Subject: CVS changes: %s

...Message from rcvs...

Committed files:
        %s

Log message:
        %s
"""


class RCVS(CVS):

    FileClass = MyFile

    def __init__(self):
        CVS.__init__(self)

    def update(self, files):
        for e in self.whichentries(files, 1):
            e.update()

    def commit(self, files, message = ""):
        list = self.whichentries(files)
        if not list: return
        ok = 1
        for e in list:
            if not e.commitcheck():
                ok = 0
        if not ok:
            print("correct above errors first")
            return
        if not message:
            message = input("One-liner: ")
        committed = []
        for e in list:
            if e.commit(message):
                committed.append(e.file)
        self.mailinfo(committed, message)

    def mailinfo(self, files, message = ""):
        towhom = "sjoerd@cwi.nl, jack@cwi.nl" # XXX
        mailtext = MAILFORM % (towhom, ' '.join(files),
                                ' '.join(files), message)
        print('-'*70)
        print(mailtext)
        print('-'*70)
        ok = input("OK to mail to %s? " % towhom)
        if ok.lower().strip() in ('y', 'ye', 'yes'):
            p = os.popen(SENDMAIL, "w")
            p.write(mailtext)
            sts = p.close()
            if sts:
                print("Sendmail exit status %s" % str(sts))
            else:
                print("Mail sent.")
        else:
            print("No mail sent.")

    def report(self, files):
        for e in self.whichentries(files):
            e.report()

    def diff(self, files, opts):
        for e in self.whichentries(files):
            e.diff(opts)

    def add(self, files):
        if not files:
            raise RuntimeError("'cvs add' needs at least one file")
        list = []
        for e in self.whichentries(files, 1):
            e.add()

    def rm(self, files):
        if not files:
            raise RuntimeError("'cvs rm' needs at least one file")
        raise RuntimeError("'cvs rm' not yet imlemented")

    def log(self, files, opts):
        flags = ''
        for o, a in opts:
            flags = flags + ' ' + o + a
        for e in self.whichentries(files):
            e.log(flags)

    def whichentries(self, files, localfilestoo = 0):
        if files:
            list = []
            for file in files:
                if file in self.entries:
                    e = self.entries[file]
                else:
                    e = self.FileClass(file)
                    self.entries[file] = e
                list.append(e)
        else:
            list = list(self.entries.values())
            for file in self.proxy.listfiles():
                if file in self.entries:
                    continue
                e = self.FileClass(file)
                self.entries[file] = e
                list.append(e)
            if localfilestoo:
                for file in os.listdir(os.curdir):
                    if file not in self.entries \
                       and not self.ignored(file):
                        e = self.FileClass(file)
                        self.entries[file] = e
                        list.append(e)
            list.sort()
        if self.proxy:
            for e in list:
                if e.proxy is None:
                    e.proxy = self.proxy
        return list


class rcvs(CommandFrameWork):

    GlobalFlags = 'd:h:p:qvL'
    UsageMessage = \
"usage: rcvs [-d directory] [-h host] [-p port] [-q] [-v] [subcommand arg ...]"
    PostUsageMessage = \
            "If no subcommand is given, the status of all files is listed"

    def __init__(self):
        """Constructor."""
        CommandFrameWork.__init__(self)
        self.proxy = None
        self.cvs = RCVS()

    def close(self):
        if self.proxy:
            self.proxy._close()
        self.proxy = None

    def recurse(self):
        self.close()
        names = os.listdir(os.curdir)
        for name in names:
            if name == os.curdir or name == os.pardir:
                continue
            if name == "CVS":
                continue
            if not os.path.isdir(name):
                continue
            if os.path.islink(name):
                continue
            print("--- entering subdirectory", name, "---")
            os.chdir(name)
            try:
                if os.path.isdir("CVS"):
                    self.__class__().run()
                else:
                    self.recurse()
            finally:
                os.chdir(os.pardir)
                print("--- left subdirectory", name, "---")

    def options(self, opts):
        self.opts = opts

    def ready(self):
        import rcsclient
        self.proxy = rcsclient.openrcsclient(self.opts)
        self.cvs.setproxy(self.proxy)
        self.cvs.getentries()

    def default(self):
        self.cvs.report([])

    def do_report(self, opts, files):
        self.cvs.report(files)

    def do_update(self, opts, files):
        """update [-l] [-R] [file] ..."""
        local = DEF_LOCAL
        for o, a in opts:
            if o == '-l': local = 1
            if o == '-R': local = 0
        self.cvs.update(files)
        self.cvs.putentries()
        if not local and not files:
            self.recurse()
    flags_update = '-lR'
    do_up = do_update
    flags_up = flags_update

    def do_commit(self, opts, files):
        """commit [-m message] [file] ..."""
        message = ""
        for o, a in opts:
            if o == '-m': message = a
        self.cvs.commit(files, message)
        self.cvs.putentries()
    flags_commit = 'm:'
    do_com = do_commit
    flags_com = flags_commit

    def do_diff(self, opts, files):
        """diff [difflags] [file] ..."""
        self.cvs.diff(files, opts)
    flags_diff = 'cbitwcefhnlr:sD:S:'
    do_dif = do_diff
    flags_dif = flags_diff

    def do_add(self, opts, files):
        """add file ..."""
        if not files:
            print("'rcvs add' requires at least one file")
            return
        self.cvs.add(files)
        self.cvs.putentries()

    def do_remove(self, opts, files):
        """remove file ..."""
        if not files:
            print("'rcvs remove' requires at least one file")
            return
        self.cvs.remove(files)
        self.cvs.putentries()
    do_rm = do_remove

    def do_log(self, opts, files):
        """log [rlog-options] [file] ..."""
        self.cvs.log(files, opts)
    flags_log = 'bhLNRtd:s:V:r:'


def remove(fn):
    try:
        os.unlink(fn)
    except os.error:
        pass


def main():
    r = rcvs()
    try:
        r.run()
    finally:
        r.close()


if __name__ == "__main__":
    main()
