#!/usr/bin/env python3
"""Audit the Vexpower teaching CSV contract, not causal identification.
Usage: python3 weekly-data-audit.py mmm-practice-synthetic.csv
No third-party dependencies. Missing/invalid data is rejected, never imputed.
"""
import csv
import datetime as dt
import hashlib
import json
import math
from pathlib import Path
import re
import sys

NUMERIC = ('revenue', 'search_spend', 'social_spend', 'video_spend')

def audit(path):
    path = Path(path)
    with path.open(newline='', encoding='utf-8-sig') as source:
        reader = csv.DictReader(source)
        headers = reader.fieldnames or []
        if len(headers) != len(set(headers)):
            raise ValueError('Duplicate column names')
        missing = {'week', *NUMERIC} - set(headers)
        if missing:
            raise ValueError('Missing columns: ' + ', '.join(sorted(missing)))
        rows = list(reader)
    if len(rows) < 2:
        raise ValueError('At least two weekly observations are required')
    dates, totals = [], dict.fromkeys(NUMERIC, 0.0)
    for line, row in enumerate(rows, 2):
        value = row.get('week') or ''
        if not re.fullmatch(r'\d{4}-\d{2}-\d{2}', value):
            raise ValueError(f'Line {line}: week must be YYYY-MM-DD')
        dates.append(dt.date.fromisoformat(value))
        for col in NUMERIC:
            try:
                number = float(row[col])
            except (TypeError, ValueError):
                raise ValueError(f'Line {line}: {col} must be numeric') from None
            if not math.isfinite(number):
                raise ValueError(f'Line {line}: {col} must be finite')
            if col.endswith('_spend') and number < 0:
                raise ValueError(f'Line {line}: {col} cannot be negative')
            totals[col] += number
    if len(set(dates)) != len(dates):
        raise ValueError('Duplicate weeks')
    if dates != sorted(dates):
        raise ValueError('Weeks must be in ascending order')
    if any((b-a).days != 7 for a,b in zip(dates, dates[1:])):
        raise ValueError('Missing week or inconsistent seven-day calendar')
    return {'rows': len(rows), 'first_week': str(dates[0]), 'last_week': str(dates[-1]),
            'totals': totals, 'sha256': hashlib.sha256(path.read_bytes()).hexdigest(),
            'scope': 'Structural checks only; reconcile definitions and totals separately.'}

if __name__ == '__main__':
    if len(sys.argv) != 2:
        raise SystemExit('Usage: python3 weekly-data-audit.py input.csv')
    try:
        print(json.dumps(audit(sys.argv[1]), indent=2))
    except (ValueError, OSError) as error:
        raise SystemExit('Audit failed: ' + str(error))
