#!/usr/bin/env python3
"""Re-run the share-google-photos-album primary-docs check.

Fetches every help page in dataset.json and reads every Viallo file it cites, then
reports, per option and property, whether the sentence that backs the value is still
there. Nothing is measured off a live album, so there is no lab step to skip.

Usage: python3 check.py [--recheck] [path/to/dataset.json]
Exit 0 when every quote holds, 1 otherwise.
"""
import html
import json
import re
import subprocess
import sys
from pathlib import Path

UA = ('Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 '
      '(KHTML, like Gecko) Version/17.0 Safari/605.1.15')
REPO = Path(__file__).resolve().parents[5]


def fetch(url):
    proc = subprocess.run(
        ['curl', '-sL', '--compressed', '-m', '30', '-A', UA,
         '-H', 'Accept-Language: en-US,en', '-w', '\n%{http_code}', url],
        capture_output=True,
    )
    body, _, code = proc.stdout.decode('utf-8', 'ignore').rpartition('\n')
    return code.strip(), body


def to_text(page):
    page = re.sub(r'(?is)<(script|style)[^>]*>.*?</\1>', ' ', page)
    page = re.sub(r'<[^>]+>', ' ', page)
    return html.unescape(page)


def norm(s):
    s = (s.replace('’', "'").replace('‘', "'")
          .replace('“', '"').replace('”', '"')
          .replace('—', '-').replace('\xa0', ' '))
    s = re.sub(r'\s+', ' ', s).strip().lower()
    # Tag stripping leaves a space before the punctuation that followed a link,
    # so "Collaborate ." and "Collaborate." have to compare equal.
    return re.sub(r'\s+([.,;:!?])', r'\1', s)


def load(url):
    if url.startswith('repo:'):
        path = REPO / url[len('repo:'):]
        return ('file', norm(path.read_text(encoding='utf-8', errors='replace')))
    code, body = fetch(url)
    return (code, norm(to_text(body)))


def main():
    # --recheck re-reads the pages, which is the whole check; accepted so the
    # weekly recheck can call it uniformly.
    args = [a for a in sys.argv[1:] if a != '--recheck']
    path = Path(args[0]) if args else Path(__file__).with_name('dataset.json')
    data = json.loads(path.read_text(encoding='utf-8'))

    sources = {}
    for item in data['inputs']:
        url = item['url']
        sources[url] = load(url)
        print(f"{sources[url][0]:>4}  {url}")
    print(f"\ncheckedAt in dataset: {data['checkedAt']}\n")

    found = missing = skipped = 0

    def check(label, quotes):
        nonlocal found, missing, skipped
        if not quotes:
            skipped += 1
            print(f"SKIP     {label}: no sentence to re-read")
            return
        for q in quotes:
            status, text = sources.get(q['url']) or load(q['url'])
            if norm(q['quote']) in text:
                found += 1
                print(f"FOUND    {label} ({status})")
            else:
                missing += 1
                print(f"MISSING  {label} ({status}): {q['quote']!r} at {q['url']}")

    for row in data['results']:
        for prop in data['properties']:
            cell = row.get(prop)
            if not cell:
                continue
            check(f"{row['option']} / {data['propertyLabels'][prop]}", cell['quotes'])

    for fact in data.get('supporting', []):
        check(f"supporting / {fact['claim']}",
              [{'url': fact['url'], 'quote': q} for q in fact['quotes']])

    print(f"\n{found} quotes found, {missing} missing, {skipped} without a sentence")
    return 1 if missing else 0


if __name__ == '__main__':
    sys.exit(main())
