#!/usr/bin/env python3

import os
import sys
import pdfplumber

if len(sys.argv) != 2:
    print("usage: gen-cta-vic.py <CTA-861-I PDF>", file=sys.stderr)
    sys.exit(1)
in_path = sys.argv[1]
in_basename = os.path.basename(in_path)

tool_dir = os.path.dirname(os.path.realpath(__file__))
out_path = tool_dir + "/../cta-vic-table.c"

# Page numbers for CTA-861-I
pages = {
    "timing": (42, 45),
    "aspect_ratio": (54, 57),
}

def extract_rows(pdf, page_range):
    (first, last) = page_range
    rows = []
    for page in pdf.pages:
        if page.page_number < first or page.page_number > last:
            continue
        table = page.extract_table()
        rows += table[1:] # strip header
    return rows

def parse_vic_list(s):
    return [int(vic.strip()) for vic in s.split(",")]

def parse_interlaced(s):
    if s == "Prog":
        return "false"
    elif s == "Int":
        return "true"
    else:
        assert(False)

def parse_polarity(pol):
    if pol == "P":
        return "POSITIVE"
    elif pol == "N":
        return "NEGATIVE"
    else:
        assert(False)

pages_list = []
for type, (first, last) in pages.items():
    pages_list += list(range(first, last + 1))

with pdfplumber.open(in_path, pages=pages_list) as pdf:
    timing_rows = extract_rows(pdf, pages["timing"])
    aspect_ratio_rows = extract_rows(pdf, pages["aspect_ratio"])

format_table = {}
for row in timing_rows:
    if not row[1]:
        continue
    for vic in parse_vic_list(row[1]):
        # Note, some values have a footnote marker
        format_table[vic] = {
            "h_active": int(row[3].rstrip("b")),
            "v_active": int(row[4]),
            "interlaced": parse_interlaced(row[5]),
            "pixel_clock_hz": int(float(row[20]) * 1000 * 1000),
            "h_front": int(row[8]),
            "h_sync": int(row[9]),
            "h_back": int(row[10]),
            "h_sync_polarity": "DI_CTA_VIC_VIDEO_FORMAT_SYNC_" + parse_polarity(row[11]),
            "v_front": int(row[14]),
            "v_sync": int(row[15]),
            "v_back": int(row[16]),
            "v_sync_polarity": "DI_CTA_VIC_VIDEO_FORMAT_SYNC_" + parse_polarity(row[17]),
        }

for row in aspect_ratio_rows:
    if len(row) == 15:
        # last two pages are extracted differently by pdfplumber due to
        # grayed-out rows ("Forbidden" and "Reserved for the Future")
        row = [row[0], row[3], row[6], row[9], row[12]]
    if not row[3]:
        continue
    vic = int(row[0])
    fmt = format_table[vic]
    # Note, some values have a footnote marker
    pic_ar = row[3].rstrip("f").replace(":", "_")
    fmt["picture_aspect_ratio"] = "DI_CTA_VIC_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_" + pic_ar

max_vic = 0
for vic in format_table:
    if vic > max_vic:
        max_vic = vic

# Sanity check
for vic, fmt in format_table.items():
    assert("picture_aspect_ratio" in fmt)

with open(out_path, "w+") as f:
    f.write("/* DO NOT EDIT! This file has been generated by gen-cta-vic.py from {}. */\n\n".format(in_basename))
    f.write('#include <libdisplay-info/cta-vic.h>\n\n')
    f.write("const struct di_cta_vic_video_format _di_cta_vic_video_formats[] = {\n")
    for vic in format_table:
        f.write("\t[{}] = {{\n".format(vic))
        f.write("\t\t.vic = {{ .code = {} }},\n".format(vic))
        for k, v in format_table[vic].items():
            f.write("\t\t.{} = {},\n".format(k, v))
        f.write("\t},\n")
    f.write("};\n\n")
    f.write("const size_t _di_cta_vic_video_formats_len = {};\n".format(max_vic + 1))
