#!/usr/bin/env python

# currently only extracts text metadata

import sys

def error(msg):
    print(msg)
    sys.exit(1)

def parsestr(data, start):
    end = start + data[start:].find(b'\0')
    return end + 1, data[start:end].decode('ascii')

def parsefields(data, pos0):
    pos1, name = parsestr(data, pos0)
    pos2, version = parsestr(data, pos1)
    pos3, author = parsestr(data, pos2)
    pos4, desc = parsestr(data, pos3)
    return {'name': name, 'version': version, 'author': author, 'desc': desc}

def parse(data, pos0):
    if len(data[pos0:]) < 6:
        raise Exception('not enough data!')
    a,b,c,d,e,f = data[pos0:pos0+6]
    if a != 0xa0 or d != 0x80 or f != 0x37:
        return None
    else:
        return (e, b, c)

def toaddr(x, y):
    return x * 256 + y - 256
    
def main():
    if len(sys.argv[1:]) != 1:
        print('usage: %s ROMFILE' % sys.argv[0])
        sys.exit(1)

    f = open(sys.argv[1], 'rb')
    data = f.read()
    f.close()

    if len(data) < 6:
        return error("file too small: %d bytes" % len(data))

    (kind, x, y) = parse(data, 0)
    if kind != 0xf0:
        head = ''.join(['%02x' % n for n in data[0:6]])
        return error("file should start with 'a0____804037' but got %r" % head)

    icon_type = None
    icon_data = None

    i = 6
    while True:
        res = parse(data, i)
        if res is None:
            break
        i += 6
        kind, x, y = res
        xy = '%02x%02x' % (x, y)
        if kind == 0xf2:
            fields = parsefields(data, toaddr(x, y))
            print('fields: %r' % fields)
        elif kind == 0xf4:
            icon_type = x * 256 - y
            print('icon type: %s' % xy)
        elif kind == 0xf6:
            # TODO: extract icon data as BMP or similar
            print('icon data at %s' % xy)
        elif kind == 0xf8:
            print('maximum memory address is %s' % xy)
        elif kind == 0xfa:
            # TODO: parse manifest structure
            print('manifest data at %s' % xy)
        else:
            print('unknown field: %02x (%s)' % (kind, xy))

if __name__ == "__main__":
    main()
