#!/usr/bin/env python

from io import BytesIO, open
import struct
import hashlib
from dbparse import DBParser
import sys
from math import log

MAGIC = 0x52474442
VERSION = 20

if len(sys.argv) < 3:
    print('Usage: %s output-file input-file' % sys.argv[0])
    sys.exit(2)

def create_rules(countries):
    result = {}
    for c in countries.values():
        for rule in c.permissions:
            result[rule] = 1
    return list(result)

def create_collections(countries):
    result = {}
    for c in countries.values():
        result[(c.permissions, c.dfs_region)] = 1
    return list(result)

def create_wmms(countries):
    result = {}
    for c in countries.values():
        for rule in c.permissions:
            if rule.wmmrule is not None:
                result[rule.wmmrule] = 1
    return list(result)

def be32(output, val):
    output.write(struct.pack('>I', val))
def be16(output, val):
    output.write(struct.pack('>H', val))

class PTR(object):
    def __init__(self, output):
        self._output = output
        self._pos = output.tell()
        be16(output, 0)
        self._written = False

    def set(self, val=None):
        if val is None:
            val = self._output.tell()
        assert val & 3 == 0
        self._offset = val
        pos = self._output.tell()
        self._output.seek(self._pos)
        be16(self._output, val >> 2)
        self._output.seek(pos)
        self._written = True

    def get(self):
        return self._offset

    @property
    def written(self):
        return self._written

p = DBParser()
countries = p.parse(open(sys.argv[2], 'r', encoding='utf-8'))
rules = create_rules(countries)
rules.sort()
collections = create_collections(countries)
collections.sort()
wmms = create_wmms(countries)
wmms.sort()

output = BytesIO()

# struct regdb_file_header
be32(output, MAGIC)
be32(output, VERSION)

country_ptrs = {}
countrynames = list(countries)
countrynames.sort()
for alpha2 in countrynames:
    coll = countries[alpha2]
    output.write(struct.pack('>BB', alpha2[0], alpha2[1]))
    country_ptrs[alpha2] = PTR(output)
output.write(b'\x00' * 4)

wmmdb = {}
for w in wmms:
    assert output.tell() & 3 == 0
    wmmdb[w] = output.tell() >> 2
    for r in w._as_tuple():
        ecw = int(log(r[0] + 1, 2)) << 4 | int(log(r[1] + 1, 2))
        ac = (ecw, r[2],r[3])
        output.write(struct.pack('>BBH', *ac))

reg_rules = {}
flags = 0
for reg_rule in rules:
    freq_range, power_rule, wmm_rule = reg_rule.freqband, reg_rule.power, reg_rule.wmmrule
    reg_rules[reg_rule] = output.tell()
    assert power_rule.max_ant_gain == 0
    flags = 0
    # convert to new rule flags
    assert reg_rule.flags & ~0x899 == 0
    if reg_rule.flags & 1<<0:
        flags |= 1<<0
    if reg_rule.flags & 1<<3:
        flags |= 1<<1
    if reg_rule.flags & 1<<4:
        flags |= 1<<2
    if reg_rule.flags & 1<<7:
        flags |= 1<<3
    if reg_rule.flags & 1<<11:
        flags |= 1<<4
    rule_len = 16
    cac_timeout = 0 # TODO
    if not (flags & 1<<2):
        cac_timeout = 0
    if cac_timeout or wmm_rule:
        rule_len += 2
    if wmm_rule is not None:
        rule_len += 2
    output.write(struct.pack('>BBHIII', rule_len, flags, int(power_rule.max_eirp * 100),
                             int(freq_range.start * 1000), int(freq_range.end * 1000), int(freq_range.maxbw * 1000),
                             ))
    if rule_len > 16:
        output.write(struct.pack('>H', cac_timeout))

    if rule_len > 18:
        be16(output, wmmdb[wmm_rule])

    while rule_len % 4:
        output.write('\0')
        rule_len += 1

for coll in collections:
    for alpha2 in countrynames:
        if (countries[alpha2].permissions, countries[alpha2].dfs_region) == coll:
            assert not country_ptrs[alpha2].written
            country_ptrs[alpha2].set()
    slen = 3
    output.write(struct.pack('>BBBx', slen, len(list(coll[0])), coll[1]))
    coll = list(coll[0])
    for regrule in coll:
        be16(output, reg_rules[regrule] >> 2)
    if len(coll) % 2:
        be16(output, 0)

for alpha2 in countrynames:
    assert country_ptrs[alpha2].written

outfile = open(sys.argv[1], 'wb')
outfile.write(output.getvalue())
