#!/usr/bin/env python3

HEADERS = [
    (':authority', 0),
    (':method', 1),
    (':method', 2),
    (':path', 3),
    (':path', 4),
    (':scheme', 5),
    (':scheme', 6),
    (':status', 7),
    (':status', 8),
    (':status', 9),
    (':status', 10),
    (':status', 11),
    (':status', 12),
    (':status', 13),
    ('accept-charset', 14),
    ('accept-encoding', 15),
    ('accept-language', 16),
    ('accept-ranges', 17),
    ('accept', 18),
    ('access-control-allow-origin', 19),
    ('age', 20),
    ('allow', 21),
    ('authorization', 22),
    ('cache-control', 23),
    ('content-disposition', 24),
    ('content-encoding', 25),
    ('content-language', 26),
    ('content-length', 27),
    ('content-location', 28),
    ('content-range', 29),
    ('content-type', 30),
    ('cookie', 31),
    ('date', 32),
    ('etag', 33),
    ('expect', 34),
    ('expires', 35),
    ('from', 36),
    ('host', 37),
    ('if-match', 38),
    ('if-modified-since', 39),
    ('if-none-match', 40),
    ('if-range', 41),
    ('if-unmodified-since', 42),
    ('last-modified', 43),
    ('link', 44),
    ('location', 45),
    ('max-forwards', 46),
    ('proxy-authenticate', 47),
    ('proxy-authorization', 48),
    ('range', 49),
    ('referer', 50),
    ('refresh', 51),
    ('retry-after', 52),
    ('server', 53),
    ('set-cookie', 54),
    ('strict-transport-security', 55),
    ('transfer-encoding', 56),
    ('user-agent', 57),
    ('vary', 58),
    ('via', 59),
    ('www-authenticate', 60),
    ('te', None),
    ('connection', None),
    ('keep-alive',None),
    ('proxy-connection', None),
    ('upgrade', None),
    (':protocol', None),
]

def to_enum_hd(k):
    res = 'NGHTTP2_TOKEN_'
    for c in k.upper():
        if c == ':' or c == '-':
            res += '_'
            continue
        res += c
    return res

def build_header(headers):
    res = {}
    for k, _ in headers:
        size = len(k)
        if size not in res:
            res[size] = {}
        ent = res[size]
        c = k[-1]
        if c not in ent:
            ent[c] = []
        if k not in ent[c]:
            ent[c].append(k)

    return res

def gen_enum():
    name = ''
    print('typedef enum {')
    for k, token in HEADERS:
        if token is None:
            print('  {},'.format(to_enum_hd(k)))
        else:
            if name != k:
                name = k
                print('  {} = {},'.format(to_enum_hd(k), token))
    print('} nghttp2_token;')

def gen_index_header():
    print('''\
static int32_t lookup_token(const uint8_t *name, size_t namelen) {
  switch (namelen) {''')
    b = build_header(HEADERS)
    for size in sorted(b.keys()):
        ents = b[size]
        print('''\
  case {}:'''.format(size))
        print('''\
    switch (name[{}]) {{'''.format(size - 1))
        for c in sorted(ents.keys()):
            headers = sorted(ents[c])
            print('''\
    case '{}':'''.format(c))
            for k in headers:
                print('''\
      if (memeq("{}", name, {})) {{
        return {};
      }}'''.format(k[:-1], size - 1, to_enum_hd(k)))
            print('''\
      break;''')
        print('''\
    }
    break;''')
    print('''\
  }
  return -1;
}''')

if __name__ == '__main__':
    gen_enum()
    print()
    gen_index_header()
