#!/usr/bin/env python3

import datetime
import glob
import re

FILENAME = '0000-snapshot-of-project-ncurses-label-v6_1_20180602.patch'
CRLF = [
    'package/mingw-ncurses.nsi'
]

def load_patch(filename):
    with open(filename) as f:
        return f.read().split('\n')

def munge_patch(lines):
    ret = []

    # print(lines[:4],'\n****************************************************************\n')

    path = lines[3][6:]
    ret += ['Index: {path}'.format(path=path)]

    id_lines = [line for line in lines if '$Id:' in line]
    # print(id_lines)

    dates = []

    for id_line in id_lines:
        id_str = id_line[id_line.index('$'):1+id_line.rindex('$')]
        vers = id_str.split(' ')[2]
        if id_line[0] == '-':
            ret += [
                'Prereq:  {vers} '.format(vers=vers),
            ]

        date_str = ' '.join(id_str.split(' ')[3:5])

        dt = datetime.datetime.strptime(date_str, '%Y/%m/%d %H:%M:%S')
        dates += [dt]

    if dates:
        # print(dates)
        ret += ['{}\t{:%Y-%m-%d %H:%M:%S.%f000 +0000}'.format(a, b) for a, b in zip(lines[2:4], dates)]
        #ret += lines[2:4]
    else:
        ret += lines[2:4]

    if path in CRLF:
        for line in lines[4:]:
            if line.startswith('@'):
                ret.append(line)
            else:
                ret.append(line+'\r')
    else:
        ret += lines[4:]
    return '\n'.join(ret)

def inject_date_1(patch, old, new):
    lines = patch.split('\n')
    x = 1 if lines[1].startswith('Prereq:') else 0

    if not lines[1+x].endswith('+0000'):
        lines[1+x] = '{}\t{:%Y-%m-%d %H:%M:%S.%f000 +0000}'.format(lines[1+x], old)
    if not lines[2+x].endswith('+0000'):
        lines[2+x] = '{}\t{:%Y-%m-%d %H:%M:%S.%f000 +0000}'.format(lines[2+x], new)

    return '\n'.join(lines)

def inject_dates(patches):
    deb_changelog_hunk = [patch for patch in patches if patch.startswith('Index: package/debian/changelog')][0]
    old_date_str = re.search(r'\n- [^\n]+>  ([^\n]+)', deb_changelog_hunk).group(1)
    new_date_str = re.search(r'\n\+ [^\n]+>  ([^\n]+)', deb_changelog_hunk).group(1)
    old_date = datetime.datetime.strptime(old_date_str, '%a, %d %b %Y %H:%M:%S %z').astimezone(tz=datetime.timezone.utc)
    new_date = datetime.datetime.strptime(new_date_str, '%a, %d %b %Y %H:%M:%S %z').astimezone(tz=datetime.timezone.utc)
    return [inject_date_1(patch, old_date, new_date) for patch in patches]

def inject_path_1(patch, old, new):

    return patch.replace(
        '--- a/', '--- {}/'.format(old), 1
    ).replace(
        '+++ b/', '+++ {}/'.format(new), 1
    )

def inject_path_and_combine(patches):
    news_patch = [p for p in patches if p.startswith('Index: NEWS')][0]
    new_date = re.search(r'\n\+(\d{8})\n', news_patch).group(1)
    old_date = re.search(r'\n\+\n (\d{8})\n', news_patch).group(1)
    new_path = 'ncurses-6.1-' + new_date
    old_path = 'ncurses-6.1-' + old_date + '+'
    with open('../msgs/{}.hdr'.format(new_date)) as f:
        hdr = f.read()

    patch = hdr + '\n'.join([inject_path_1(patch, old_path, new_path) for patch in patches])

    with open('../re-patches/ncurses-6.1-{}.re.patch'.format(new_date), 'w') as f:
        f.write(patch)
        f.write('\n')

    return patch[:patch.index('\n')]

def do_one_patch(filename):
    lines = load_patch(filename)
    starts = [i for i, line in enumerate(lines) if line.startswith('diff')]
    ends = starts[1:] + [len(lines)-4]
    patches = [munge_patch(lines[s:e]) for s, e in zip(starts, ends)]
    patches = inject_dates(patches)
    patch = inject_path_and_combine(patches)

def main():
    for filename in glob.glob('../patches/*.patch'):
        do_one_patch(filename)

if __name__ == '__main__':
    main()

