#!/usr/bin/python
#    Copyright © 2008 Jeff Epler <jepler@unpythonic.net>
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import sha, sys, getopt

def make_hash(s):
    return sha.new(s).hexdigest()

def hiff(lines, firstchars=" -"):
    st = 0
    for l in lines:
        if l.startswith("@@"): st = 1
        elif l.startswith("+++"): st = 0

        if st == 1:
            if not l[:1] in firstchars: yield l
            else: yield "&" + l[:1] + make_hash(l[1:]) + "\n"
        else:
            yield l

def dehiff(lines, hashes):
    for l in lines:
        if not l.startswith("&"):
            yield l
        else:
            c = l[1:2]
            h = l[2:].strip()
            try:
                yield c + hashes[h]
            except KeyError:
                yield c + "&" + h

def get_hashes(lines, result=None):
    if result is None: result = {}
    for l in lines:
        result[make_hash(l)] = l
    return result

def main(args):
    HIFF, DEHIFF = range(2)
    assert HIFF != DEHIFF
    action = HIFF
    sources = []

    opts, args = getopt.getopt(args, "hds:", ['hiff', 'dehiff', 'source='])
    for k, v in opts:
        if k in ('-h', '--hiff'): action = HIFF
        elif k in ('-d', '--dehiff'): action = DEHIFF
        elif k in ('-s', '--source'): sources.append(v)
        else: usage("Unknown option %r", k)

    if action == HIFF:
        if sources:
            usage("-s makes no sense when hiffing a patch")
        for line in hiff(sys.stdin): sys.stdout.write(line)
    else:
        hashes = {}
        for f in sources: get_hashes(open(f), hashes)
        for line in dehiff(sys.stdin, hashes): sys.stdout.write(line)

if __name__ == '__main__': main(sys.argv[1:])
