#!/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\" ?")
        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("config --get %s" % variable)[0].rstrip()
        except:
            return None

    def set_config(self, variable, value):
        try:
            self.git("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

