#!/usr/bin/env python3
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>

# This script uses the database of mimetypes distributed here: https://github.com/jshttp/mime-db
# to produce the X-header file mimetypes.inc

import os
import argparse

CRC32_POLY = 0xEDB88320
CRC32C_POLY = 0x82F63B78
CRC64_XZ_POLY = 0xC96C5795D7870F42
CRC64_NVME_POLY = 0x9A6C9329AC4BC9B5

LICENSE_HEADER = """// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>"""

def write_crc32_table(f, name, poly):
    f.write(f'static const uint32_t {name}[256] = {{')
    for i in range(0, 256):
        value = i
        for j in range(0, 8):
            value = (value >> 1) ^ (poly if value & 1 else 0)

        if i % 6 == 0:
            f.write('\n   ')
        f.write(f' 0x{value:08X}u,')
    f.write('\n};\n\n')

def write_crc64_tables(f, name, poly):
    for table in range(0, 16):
        count = table * 8 + 8

        f.write(f'static const uint64_t {name}{table}[256] = {{')
        for i in range(0, 256):
            value = i
            for j in range(0, count):
                value = (value >> 1) ^ (poly if value & 1 else 0)

            if i % 4 == 0:
                f.write('\n   ')
            f.write(f' 0x{value:016X}ull,')
        f.write('\n};\n')

    f.write('\n')

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description = 'Update CRC tables header file')
    parser.add_argument('-O', '--output_file', dest = 'output_file', action = 'store', help = 'Output file')
    args = parser.parse_args()

    if args.output_file is None:
        output_file = os.path.join(os.path.dirname(__file__), 'crc.inc')
    else:
        output_file = args.output_file

    with open(output_file, 'w') as f:
        f.write(f'''{LICENSE_HEADER}

// This file is autogenerated by crc_gen.py

namespace K {{

''')

        write_crc32_table(f, 'Crc32Table', CRC32_POLY)
        write_crc32_table(f, 'Crc32CTable', CRC32C_POLY)
        write_crc64_tables(f, 'Crc64XzTable', CRC64_XZ_POLY)
        write_crc64_tables(f, 'Crc64NvmeTable', CRC64_NVME_POLY)

        f.write('}\n')
