#!/usr/bin/env python3
"""Compare saved OCR text to authored body text; does not execute OCR."""
import csv
import json
from pathlib import Path
import unicodedata

DIRECTORY = Path(__file__).resolve().parent


def normalize(text):
    return "".join(char for char in unicodedata.normalize("NFC", text) if not char.isspace())


def distance(expected, actual):
    row = list(range(len(actual) + 1))
    for i, left in enumerate(expected, 1):
        following = [i]
        for j, right in enumerate(actual, 1):
            following.append(min(following[-1] + 1, row[j] + 1, row[j - 1] + (left != right)))
        row = following
    return row[-1]


corpus = json.loads((DIRECTORY / "sample-manifest.json").read_text(encoding="utf-8"))
outputs = json.loads((DIRECTORY / "ocr-results.json").read_text(encoding="utf-8"))
columns = corpus["body_columns_in_reading_order"]
rows = []
for test in outputs["results"]:
    expected = "".join(columns)
    if test["id"].startswith("body-column-"):
        expected = columns[int(test["id"].split("-")[2]) - 1]
    normalized_expected = normalize(expected)
    normalized_actual = normalize(test["raw_text"])
    rows.append({
        "test": test["id"],
        "expected_body_codepoints": len(normalized_expected),
        "normalized_levenshtein_distance": distance(normalized_expected, normalized_actual),
        "body_exact_match_after_whitespace_removal": normalized_expected == normalized_actual,
        "expected": normalized_expected,
        "observed": normalized_actual,
    })
with (DIRECTORY / "body-comparison.csv").open("w", encoding="utf-8", newline="") as handle:
    writer = csv.DictWriter(handle, fieldnames=list(rows[0]))
    writer.writeheader()
    writer.writerows(rows)
print(json.dumps(rows, ensure_ascii=False, indent=2))
