import copy
import csv
import hashlib
import json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
REVIEWED = '2026-09-18'
DATA = ROOT / 'data/website-historical-nuclear-2026-09-18'
RESEARCH = ROOT / 'data/historical-nuclear-plans-2026-09-17'
SELECTION = 'historical-nuclear-selection'
SOURCE_DETAILS = {
    'bfe-5473': (
        'ensi-historical-projects', 'ENSI comparison of the three proposed nuclear plants', 'ENSI; archived by BFE',
        'Page 1: proposed power classes, cooling, geology and seismic investigations; page 2: Beznau flood protection; page 3: project organisation.',
        'Historical general-licence assessment, published 15 November 2010. Power classes describe proposed plants, with a 20% tolerance. Niederamt has alternative classes, not two units. Conditions and findings belong to that assessment stage.',
    ),
    'bfe-5605': (
        'kns-niederamt-2010', 'Niederamt: Nuclear Safety Commission opinion', 'KNS; archived by BFE',
        'Printed page 28, section 3.3, recommendations 3, 4.1.6 and 4.1.7: owner organisation, geological investigations and reliable grid connection.',
        'Opinion dated 15 December 2010; BFE catalogue publication dated 10 January 2011. Recommendations describe the historical project. Their resolution by later work has not been established in this review.',
    ),
    'bfe-nuclear-history': (
        'bfe-nuclear-history', 'Swiss nuclear development and the withdrawn applications', 'BFE',
        'Paragraph beginning “2008 wurden”: three applications, suspension after Fukushima in March 2011 and withdrawal in 2016.',
        'Undated BFE history page, archived 17 September 2026. Used for historical chronology; current policy is covered separately by the dated DETEC source.',
    ),
    'owners-withdrawal-alpiq-2016': (
        'nuclear-applications-withdrawal-2016', 'Owners withdraw the nuclear general-licence applications', 'Alpiq, Axpo and BKW',
        'Joint announcement dated 12 October 2016, opening two paragraphs.',
        'The owners cite both changed market conditions and the political direction. Withdrawal of the applications does not establish that earlier site investigations have no reuse value.',
    ),
}


def load(path):
    return json.loads(path.read_text())


def write(path, value):
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(value, indent=2, ensure_ascii=False, allow_nan=False) + '\n')


def artifact(path, download=None):
    content = path.read_bytes()
    row = dict(path=str(path.relative_to(ROOT)), sha256=hashlib.sha256(content).hexdigest(), bytes=len(content))
    if download:
        row['download'] = download
        target = ROOT / 'website/public' / download.lstrip('/')
        target.parent.mkdir(parents=True, exist_ok=True)
        target.write_bytes(content)
    return row


def main():
    prior = load(ROOT / 'data/website-nuclear-delivery-2026-09-17/catalog.json')
    catalog = copy.deepcopy(prior)
    research = load(RESEARCH / 'projects-and-reuse.json')
    originals = {row['source_id']: row for row in load(RESEARCH / 'source-catalog.json')['sources']}
    for source_id, (public_id, title, publisher, locator, note) in SOURCE_DETAILS.items():
        original = originals[source_id]
        assert original['status'] == 'archived'
        raw = artifact(ROOT / original['path'])
        assert (raw['sha256'], raw['bytes']) == (original['sha256'], original['bytes'])
        files = [raw, artifact(ROOT / original['text_path'])]
        metadata = (ROOT / original['path']).with_suffix('.source.json')
        if metadata.exists():
            files.append(artifact(metadata))
        catalog['sources'].append(dict(
            id=public_id, title=title, publisher=publisher, kind='primary', url=original['url'],
            publicationDate=original.get('document_date') or original.get('publication_date'),
            edition=original.get('date_note') or original.get('publication_date') or 'Snapshot retrieved 17 September 2026',
            retrievedAt=original['retrieved_at_utc'], reviewedAt=REVIEWED, locator=locator, note=note, artifacts=files,
        ))

    added = []

    def add(claim_id, label, value, unit, definition):
        row = dict(id=claim_id, label=label, value=value, unit=unit, status='scenario',
                   period='2008 applications, described in ENSI’s 2010 assessment', definition=definition,
                   limitation='Historical proposal, never built under these applications. It establishes neither installed capacity nor the capacity of a future Swiss project.',
                   sources=['ensi-historical-projects', SELECTION], reviewedAt=REVIEWED,
                   formula='Direct transcription of the applicant’s proposed parameter as reported by ENSI; no output or delivery projection.')
        added.append(row)
        catalog['claims'].append(row)

    summaries = {
        'ekkb': ('Beznau', 'Flood protection, including effects on neighbouring nuclear facilities.', 'ensi-historical-projects', 'Page 2, hydrology paragraph'),
        'ekkm': ('Mühleberg — Niederruntigen', 'Slope stability, landslides and rockfall.', 'ensi-historical-projects', 'Page 1, final paragraph'),
        'kkn': ('Niederamt — near Gösgen', 'Regional geology and reliable grid connection, with any necessary network expansion.', 'kns-niederamt-2010', 'Printed page 28, recommendations 4.1.6 and 4.1.7'),
    }
    projects = []
    for original in research['projects']:
        project_id = original['project_id']
        label, followup, source_id, locator = summaries[project_id]
        assert original['power_tolerance_percent'] == 20
        assert original['estimated_years_saved'] is None and original['estimated_chf_saved'] is None
        claims = []
        for index, capacity in enumerate(original['power_class_mwe']):
            claim_id = f'historical-{project_id}-power-{index + 1}'
            add(claim_id, f'{original["name"]}: proposed power class {index + 1}', capacity, 'MW electrical',
                'Proposed electrical power class. Niederamt’s two classes are alternatives for one plant. The common tolerance is recorded separately; no annual generation or capacity factor is inferred.')
            claims.append(claim_id)
        projects.append(dict(
            id=project_id, name=original['name'], label=label, power_classes_mwe=original['power_class_mwe'],
            power_claims=claims, power_tolerance_percent=original['power_tolerance_percent'],
            cooling=original['cooling'], historical_followup=followup, followup_source=source_id, followup_locator=locator,
            evidence_status='historical_proposal', current_resolution='Check later evidence; unresolved by this review',
            estimated_years_saved=None, estimated_chf_saved=None,
        ))
    assert [row['power_classes_mwe'] for row in projects] == [[1450], [1450], [1100, 1600]]
    add('historical-nuclear-power-tolerance', 'Historical proposed power tolerance', 20, '%',
        'The applications permitted a deviation of plus or minus 20% from each listed electrical power class. This is a design allowance, not a statistical uncertainty interval.')

    chronology = [
        dict(date='2008', title='Applications submitted', text='Three projects enter the general-licence process.', source='bfe-nuclear-history'),
        dict(date='November 2010', title='Site assessments', text='ENSI finds geological conditions suitable in principle and requires further investigations.', source='ensi-historical-projects'),
        dict(date='March 2011', title='Procedures suspended', text='The government suspends the procedures after Fukushima.', source='bfe-nuclear-history'),
        dict(date='October 2016', title='Applications withdrawn', text='Owners cite changed market conditions and the political direction.', source='nuclear-applications-withdrawal-2016'),
    ]
    findings = [
        dict(id='historical-cooling', status='historical_proposal', text='All three proposals included hybrid cooling towers.', sources=['ensi-historical-projects'], locator='Page 1'),
        dict(id='historical-study-scope', status='historical_assessment', text='The assessments cover geological and flood investigations, cooling concepts, generic plant dimensions and project organisation.', sources=['ensi-historical-projects'], locator='Pages 1–3'),
        dict(id='reuse-recommendation', status='editorial_recommendation', text='Start a comparative site study with these three dossiers. Check later findings, current conditions and requirements, cooling and grid costs, land access and owner willingness before selecting a site.', sources=['ensi-historical-projects', 'kns-niederamt-2010', 'nuclear-applications-withdrawal-2016']),
        dict(id='reuse-savings', status='unresolved', text='No defensible estimate of development time or money saved has been established. Retain the existing conditional delivery dates.', sources=[SELECTION]),
    ]
    dataset = dict(reviewedAt=REVIEWED, projects=projects, chronology=chronology, findings=findings, claims=added,
                   boundary='Selected historical proposals and assessment findings. No current site approval, selected reactor, owner commitment or aggregate build programme is inferred.',
                   inputs=[artifact(RESEARCH / name) for name in ['projects-and-reuse.json', 'source-catalog.json']])
    write(DATA / 'evidence.json', dataset)
    files = [artifact(DATA / 'evidence.json', '/downloads/historical-nuclear/evidence.json'),
             artifact(Path(__file__).resolve(), '/downloads/historical-nuclear/build_website_historical_nuclear.py')]
    fields = ['id', 'name', 'power_class_mwe', 'power_tolerance_percent', 'cooling', 'historical_followup', 'followup_source', 'followup_locator', 'evidence_status', 'current_resolution', 'estimated_years_saved', 'estimated_chf_saved']
    with (DATA / 'proposals.csv').open('w', newline='') as stream:
        writer = csv.DictWriter(stream, fieldnames=fields, extrasaction='ignore', lineterminator='\n')
        writer.writeheader()
        for project in projects:
            for capacity in project['power_classes_mwe']:
                writer.writerow(dict(project, power_class_mwe=capacity))
    files.append(artifact(DATA / 'proposals.csv', '/downloads/historical-nuclear/proposals.csv'))
    catalog['sources'].append(dict(
        id=SELECTION, title='Historical nuclear proposals: selected data and reuse assessment', publisher='WattInfo',
        kind='project-calculation', url='/downloads/historical-nuclear/evidence.json', publicationDate=REVIEWED,
        edition='Historical proposals, reviewed 18 September 2026', retrievedAt=REVIEWED, reviewedAt=REVIEWED,
        locator='projects; chronology; findings; claims; linked primary sources', artifacts=files,
        note='Directly transcribed proposal parameters and selected historical findings, with an editorial reuse recommendation. Niederamt’s two power classes are alternatives. Reuse savings remain unquantified; the conditional Swiss delivery scenarios are unchanged. Blank savings cells in the CSV mean unknown, not zero.',
    ))
    for collection in ['sources', 'claims']:
        assert catalog[collection][:len(prior[collection])] == prior[collection]
    catalog['reviewedAt'] = REVIEWED
    for path in [DATA / 'catalog.json', ROOT / 'website/src/data/catalog.json', ROOT / 'website/public/downloads/catalog.json']:
        write(path, catalog)
    print(f'Added {len(SOURCE_DETAILS)} primary sources, one curated record and {len(added)} historical-proposal claims.')


if __name__ == '__main__':
    main()
