#!/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
tagall = True

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","notags"])
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 ("--notags"):
        tagall = False
    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)
    if tagall :
            git.commit(change.author, change.email, change.date, change.msg, id)
    else:
            git.commit(change.author, change.email, change.date, change.msg, "import")
    if stitch == 1:
        git.clean_directories()
        stitch = 0

