#!/usr/bin/python
#
# This tool is copyright (c) 2006, Sean Estabrooks.
# It is released under the Gnu Public License, version 2.
#
# Import Perforce branches into Git repositories.
# Checking out the files is done by calling the standard p4
# client which you must have properly configured yourself
#

import marshal
import os
import sys
import time
import getopt

from signal import signal, \
   SIGPIPE, SIGINT, SIG_DFL, \
   default_int_handler

signal(SIGPIPE, SIG_DFL)
s = signal(SIGINT, SIG_DFL)
if s != default_int_handler:
   signal(SIGINT, s)


def die(msg, *args):
    for a in args:
        msg = "%s %s" % (msg, a)
    print "git-p4import fatal error:", msg
    sys.exit(1)

def usage():
    print "USAGE: git-p4import [-q|-v]  [--authors=<file>]  [-t <timezone>]  [//p4repo/path <branch>]"
    sys.exit(1)

verbosity = 1
logfile = "/dev/null"
ignore_warnings = False
stitch = 0

def report(level, msg, *args):
    global verbosity
    global logfile
    for a in args:
        msg = "%s %s" % (msg, a)
    fd = open(logfile, "a")
    fd.writelines(msg)
    fd.close()
    if level <= verbosity:
        print msg

class p4_command:
    def __init__(self, _repopath):
        try:
            global logfile
            self.userlist = {}
            if _repopath[-1] == '/':
                self.repopath = _repopath[:-1]
            else:
                self.repopath = _repopath
            if self.repopath[-4:] != "/...":
                self.repopath= "%s/..." % self.repopath
            f=os.popen('p4 -V 2>>%s'%logfile, 'rb')
            a = f.readlines()
            if f.close():
                raise
        except:
                die("Could not find the \"p4\" command")

    def p4(self, cmd, *args):
        global logfile
        cmd = "%s %s" % (cmd, ' '.join(args))
        report(2, "P4:", cmd)
        f=os.popen('p4 -G %s 2>>%s' % (cmd,logfile), 'rb')
        list = []
        while 1:
           try:
                list.append(marshal.load(f))
           except EOFError:
                break
        self.ret = f.close()
        return list

    def sync(self, id, force=False, trick=False, test=False):
        if force:
            ret = self.p4("sync -f %s@%s"%(self.repopath, id))[0]
        elif trick:
            ret = self.p4("sync -k %s@%s"%(self.repopath, id))[0]
        elif test:
            ret = self.p4("sync -n %s@%s"%(self.repopath, id))[0]
        else:
            ret = self.p4("sync    %s@%s"%(self.repopath, id))[0]
        if ret['code'] == "error":
             data = ret['data'].upper()
             if data.find('VIEW') > 0:
                 die("Perforce reports %s is not in client view"% self.repopath)
             elif data.find('UP-TO-DATE') < 0:
                 die("Could not sync files from perforce", self.repopath)

    def changes(self, since=0):
        try:
            list = []
            for rec in self.p4("changes %s@%s,#head" % (self.repopath, since+1)):
                list.append(rec['change'])
            list.reverse()
            return list
        except:
            return []

    def authors(self, filename):
        f=open(filename)
        for l in f.readlines():
            self.userlist[l[:l.find('=')].rstrip()] = \
                    (l[l.find('=')+1:l.find('<')].rstrip(),l[l.find('<')+1:l.find('>')])
        f.close()
        for f,e in self.userlist.items():
                report(2, f, ":", e[0], "  <", e[1], ">")

    def _get_user(self, id):
        if not self.userlist.has_key(id):
            try:
                user = self.p4("users", id)[0]
                self.userlist[id] = (user['FullName'], user['Email'])
            except:
                self.userlist[id] = (id, "")
        return self.userlist[id]

    def _format_date(self, ticks):
        symbol='+'
        name = time.tzname[0]
        offset = time.timezone
        if ticks[8]:
            name = time.tzname[1]
            offset = time.altzone
        if offset < 0:
            offset *= -1
            symbol = '-'
        localo = "%s%02d%02d %s" % (symbol, offset / 3600, offset % 3600, name)
        tickso = time.strftime("%a %b %d %H:%M:%S %Y", ticks)
        return "%s %s" % (tickso, localo)

    def where(self):
        try:
            return self.p4("where %s" % self.repopath)[-1]['path']
        except:
            return ""

    def describe(self, num):
        desc = self.p4("describe -s", num)[0]
        self.msg = desc['desc']
        self.author, self.email = self._get_user(desc['user'])
        self.date = self._format_date(time.localtime(long(desc['time'])))
        return self

class git_command:
    def __init__(self):
        try:
            self.version = self.git("--version")[0][12:].rstrip()
        except:
            die("Could not find the \"git\" command")
        try:
            self.gitdir = self.get_single("rev-parse --git-dir")
            report(2, "gdir:", self.gitdir)
        except:
            die("Not a git repository... did you forget to \"git init-db\" ?")
        try:
            self.cdup = self.get_single("rev-parse --show-cdup")
            if self.cdup != "":
                os.chdir(self.cdup)
            self.topdir = os.getcwd()
            report(2, "topdir:", self.topdir)
        except:
            die("Could not find top git directory")

    def git(self, cmd):
        global logfile
        report(2, "GIT:", cmd)
        f=os.popen('git %s 2>>%s' % (cmd,logfile), 'rb')
        r=f.readlines()
        self.ret = f.close()
        return r

    def get_single(self, cmd):
        return self.git(cmd)[0].rstrip()

    def current_branch(self):
        try:
            testit = self.git("rev-parse --verify HEAD")[0]
            return self.git("symbolic-ref HEAD")[0][11:].rstrip()
        except:
            return None

    def get_config(self, variable):
        try:
            return self.git("repo-config --get %s" % variable)[0].rstrip()
        except:
            return None

    def set_config(self, variable, value):
        try:
            self.git("repo-config %s %s"%(variable, value) )
        except:
            die("Could not set %s to " % variable, value)

    def make_tag(self, name, head):
        self.git("tag -f %s %s"%(name,head))

    def top_change(self, branch):
        try:
            a=self.get_single("name-rev --tags refs/heads/%s" % branch)
            loc = a.find(' tags/') + 6
            if a[loc:loc+3] != "p4/":
                raise
            return int(a[loc+3:][:-2])
        except:
            return 0

    def update_index(self):
        self.git("ls-files -m -d -o -z | git update-index --add --remove -z --stdin")

    def checkout(self, branch):
        self.git("checkout %s" % branch)

    def repoint_head(self, branch):
        self.git("symbolic-ref HEAD refs/heads/%s" % branch)

    def remove_files(self):
        self.git("ls-files | xargs rm")

    def clean_directories(self):
        self.git("clean -d")

    def fresh_branch(self, branch):
        report(1, "Creating new branch", branch)
        self.git("ls-files | xargs rm")
        os.remove(".git/index")
        self.repoint_head(branch)
        self.git("clean -d")

    def basedir(self):
        return self.topdir

    def commit(self, author, email, date, msg, id):
        self.update_index()
        fd=open(".msg", "w")
        fd.writelines(msg)
        fd.close()
        try:
                current = self.get_single("rev-parse --verify HEAD")
                head = "-p HEAD"
        except:
                current = ""
                head = ""
        tree = self.get_single("write-tree")
        for r,l in [('DATE',date),('NAME',author),('EMAIL',email)]:
            os.environ['GIT_AUTHOR_%s'%r] = l
            os.environ['GIT_COMMITTER_%s'%r] = l
        commit = self.get_single("commit-tree %s %s < .msg" % (tree,head))
        os.remove(".msg")
        self.make_tag("p4/%s"%id, commit)
        self.git("update-ref HEAD %s %s" % (commit, current) )


try:
    opts, args = getopt.getopt(sys.argv[1:], "qhvt:",
                    ["authors=","help","stitch=","timezone=","log=","ignore"])
except getopt.GetoptError:
    usage()

for o, a in opts:
    if o == "-q":
        verbosity = 0
    if o == "-v":
        verbosity += 1
    if o in ("--log"):
        logfile = a
    if o in ("-h", "--help"):
        usage()
    if o in ("--ignore"):
        ignore_warnings = True

git = git_command()
branch=git.current_branch()

for o, a in opts:
    if o in ("-t", "--timezone"):
        git.set_config("perforce.timezone", a)
    if o in ("--stitch"):
        git.set_config("perforce.%s.path" % branch, a)
        stitch = 1

if len(args) == 2:
    branch = args[1]
    git.checkout(branch)
    if branch == git.current_branch():
        die("Branch %s already exists!" % branch)
    report(1, "Setting perforce to ", args[0])
    git.set_config("perforce.%s.path" % branch, args[0])
elif len(args) != 0:
    die("You must specify the perforce //depot/path and git branch")

p4path = git.get_config("perforce.%s.path" % branch)
if p4path == None:
    die("Do not know Perforce //depot/path for git branch", branch)

p4 = p4_command(p4path)

for o, a in opts:
    if o in ("-a", "--authors"):
        p4.authors(a)

localdir = git.basedir()
if p4.where()[:len(localdir)] != localdir:
    report(1, "**WARNING** Appears p4 client is misconfigured")
    report(1, "   for sync from %s to %s" % (p4.repopath, localdir))
    if ignore_warnings != True:
        die("Reconfigure or use \"--ignore\" on command line")

if stitch == 0:
    top = git.top_change(branch)
else:
    top = 0
changes = p4.changes(top)
count = len(changes)
if count == 0:
    report(1, "Already up to date...")
    sys.exit(0)

ptz = git.get_config("perforce.timezone")
if ptz:
    report(1, "Setting timezone to", ptz)
    os.environ['TZ'] = ptz
    time.tzset()

if stitch == 1:
    git.remove_files()
    git.clean_directories()
    p4.sync(changes[0], force=True)
elif top == 0 and branch != git.current_branch():
    p4.sync(changes[0], test=True)
    report(1, "Creating new initial commit");
    git.fresh_branch(branch)
    p4.sync(changes[0], force=True)
else:
    p4.sync(changes[0], trick=True)

report(1, "processing %s changes from p4 (%s) to git (%s)" % (count, p4.repopath, branch))
for id in changes:
    report(1, "Importing changeset", id)
    change = p4.describe(id)
    p4.sync(id)
    git.commit(change.author, change.email, change.date, change.msg, id)
    if stitch == 1:
        git.clean_directories()
        stitch = 0

