import gzip
import os

UNICODEDATA="UnicodeData.txt"
EASTASIANWIDTHS="EastAsianWidth.txt"
NAMEALIASES="NameAliases.txt"

UNICODEDATA_3_2_0="UnicodeData-3.2.0.txt"
EASTASIANWIDTHS_3_2_0="EastAsianWidth-3.2.0.txt"

def readdatafile(filename):
    with open(filename) as f:
        for line in f:
            line = line.split('#')[0].strip()
            if line:
                yield line.split(';')

def builddb(raw_data):
    data = {}
    i = 0
    l = len(raw_data)
    while i < l:
        info = raw_data[i]
        if info[1][0] == '<' and info[1].endswith('First>'):
            first = raw_data[i]
            i += 1
            last = raw_data[i]

            data['{0}..{1}'.format(first[0], last[0])] = ['{0}..{1}'.format(first[1], last[1])] + first[2:10]
        else:
            data[info[0]] = info[1:10]

        i += 1

    return data

def add_eawidths(data, filename):
    for eawidth in readdatafile(filename):
        if eawidth[0] in data:
            data[eawidth[0]] += [eawidth[1]]

    return data

def add_name_aliases(data, filename):
    assert all(len(d) == 10 for d in data.values())
    if filename:
        for aliases in readdatafile(filename):
            if aliases[0] in data:
                data[aliases[0]] += [aliases[1]]

    return data

def load_data(unicode_data, east_asian_widths, name_aliases):
    raw_data = list(readdatafile(unicode_data))
    data = builddb(raw_data)
    data = add_eawidths(data, east_asian_widths)

    data = add_name_aliases(data, name_aliases)
    return data

def generate_gz(filename, unicode_data, east_asian_widths, name_aliases=None):
    data = load_data(unicode_data, east_asian_widths, name_aliases)

    with open(filename, 'wb') as f, gzip.GzipFile(fileobj=f, mode='wb', mtime=0) as gz:
        gz.write('# This file is generated by {0} from {1} and {2}. Do not modify it directly.\n'.format(os.path.basename(__file__), unicode_data, east_asian_widths).encode())

        for char, info in sorted(data.items(), key=lambda x: int(x[0].split('.')[0], 16)):
            gz.write((';'.join([char] + info) + '\n').encode())

if __name__ == "__main__":
    generate_gz('IPyUnicodeData.txt.gz', UNICODEDATA, EASTASIANWIDTHS, NAMEALIASES)
    generate_gz('IPyUnicodeData-3.2.0.txt.gz', UNICODEDATA_3_2_0, EASTASIANWIDTHS_3_2_0)
