"""Run the seven extractors from the article on the three fixture PDFs and
write extraction-results.csv.

Requires: pdftotext (poppler) on PATH, pypdf, pdfminer.six, PyMuPDF.
Tested with pdftotext 26.08.0, pypdf 5.1.0, pdfminer.six 20240706,
PyMuPDF 1.24.14. Run in the folder that holds the fixture PDFs and
check_reading_order.py:

    python run_extractors.py
"""
import csv
import subprocess
import sys

import fitz
import pypdf
from pdfminer.high_level import extract_text

FILES = [
    "two-column-stream-logical",
    "two-column-stream-rowwise",
    "two-column-no-figure-rowwise",
]


def pdftotext(*flags):
    def run(pdf):
        return subprocess.run(["pdftotext", *flags, pdf, "-"], capture_output=True, text=True, check=True).stdout
    return run


EXTRACTORS = {
    "pdftotext (default)": pdftotext(),
    "pdftotext -raw": pdftotext("-raw"),
    "pdftotext -layout": pdftotext("-layout"),
    "pypdf extract_text()": lambda pdf: pypdf.PdfReader(pdf).pages[0].extract_text(),
    "pdfminer.six extract_text()": extract_text,
    "PyMuPDF get_text()": lambda pdf: fitz.open(pdf)[0].get_text(),
    "PyMuPDF get_text(sort=True)": lambda pdf: fitz.open(pdf)[0].get_text(sort=True),
}


def check(text):
    path = "_extracted.txt"
    with open(path, "w", encoding="utf-8") as f:
        f.write(text)
    out = subprocess.run([sys.executable, "check_reading_order.py", path], capture_output=True, text=True, check=True).stdout
    fields = dict(line.split(":", 1) for line in out.splitlines())
    return fields["Order found"].strip(), fields["Mixed lines"].strip()


with open("extraction-results.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f, lineterminator="\n")
    writer.writerow(["extractor"] + [n + " order" for n in FILES] + [n + " mixed lines" for n in FILES])
    for name, extract in EXTRACTORS.items():
        results = [check(extract(n + ".pdf")) for n in FILES]
        writer.writerow([name] + [r[0] for r in results] + [r[1] for r in results])
        print(name, "|", " | ".join(r[0] for r in results))
