#!/usr/bin/env python3
"""
add-pipeline-declarations.py
Inserts the `pipeline` I/O declaration into each specialist otter JSON.

Run once: python3 scripts/add-pipeline-declarations.py
Part of swp-amyw Batch 1.

AUDIT NOTES (inline justifications for dep changes):
- auth-otter: was ['pages', 'dashboard', 'workflow', 'geo'] in PHASE_DEPENDENCIES.
  Bead 3 (swp-e4y6) changed the runtime model: AuthProvider reads _auth.json at
  runtime, no longer needs build-time route enumeration. Auth only needs
  design-language.json to extract personas/roles. Moves auth wave 4 → wave 2.

- workflow (form-wizard-otter): was [] with a Prism mock fallback comment.
  Bead swp-4071 (services hooks contract) made the workflow→api relationship
  explicit via serviceHooks referencing API endpoints. Real deps added:
  _theme.json (UI generation) and api-config.json (hook endpoint references).
"""

import json
import os

SRC_DIR = os.path.join(os.path.dirname(__file__), '..', 'src')

# Pipeline declarations keyed by otter filename (no .json extension).
# Matches the table in the swp-amyw plan.
# Null-sentinel otters (foreman, domain-expert) are skipped — they're orchestrators.
DECLARATIONS: dict[str, dict] = {
    'stackwright-pro-designer-otter': {
        'inputs': {},
        'outputs': {
            'artifact': 'design-language.json',
        },
    },
    'stackwright-pro-theme-otter': {
        'inputs': {
            'artifacts': ['design-language.json'],
        },
        'outputs': {
            'sinks': ['_theme.json'],
            'artifact': 'theme-tokens.json',
            'files': ['stackwright.theme.yml'],
        },
    },
    'stackwright-pro-api-otter': {
        'inputs': {},
        'outputs': {
            'sinks': ['_integrations.json'],
            'artifact': 'api-config.json',
            'files': ['stackwright.integrations.yml'],
        },
    },
    # AUDIT: auth moved from wave 4 → wave 2.
    # Bead 3 (swp-e4y6) changed the runtime model: AuthProvider reads
    # _auth.json at runtime; auth no longer needs build-time route enumeration.
    # Auth now only reads design-language.json to extract personas/roles.
    'stackwright-pro-auth-otter': {
        'inputs': {
            'artifacts': ['design-language.json'],
        },
        'outputs': {
            'sinks': ['_auth.json'],
            'artifact': 'auth-config.json',
            'files': [
                'stackwright.auth.yml',
                '.env.example',
                'lib/mock-auth.ts',
                'package.json',
            ],
        },
    },
    'stackwright-pro-scaffold-otter': {
        'inputs': {
            'sinks': ['_theme.json'],
            'files': ['stackwright.yml'],
        },
        'outputs': {
            'artifact': 'scaffold-manifest.json',
            'files': ['app/**'],
        },
        # scaffold-otter generates app/layout.tsx which reads _collections.json
        # and _auth.json at app build time — NOT at scaffold-otter execution time.
        'runtimeReads': ['_collections.json', '_auth.json'],
    },
    'stackwright-pro-data-otter': {
        'inputs': {
            'artifacts': ['api-config.json'],
        },
        'outputs': {
            'sinks': ['_collections.json'],
            'artifact': 'data-config.json',
            'files': ['stackwright.collections.yml'],
        },
    },
    'stackwright-pro-geo-otter': {
        'inputs': {
            'artifacts': ['data-config.json'],
        },
        'outputs': {
            'artifact': 'geo-manifest.json',
        },
    },
    # AUDIT: workflow moved from [] → real deps.
    # swp-4071 (services hooks contract) made workflow→api relationship explicit:
    # serviceHooks reference API endpoints from api-config.json.
    # UI generation requires _theme.json for component selection.
    'stackwright-pro-form-wizard-otter': {
        'inputs': {
            'sinks': ['_theme.json'],
            'artifacts': ['api-config.json'],
        },
        'outputs': {
            'artifact': 'workflow-config.json',
            'files': ['stackwright.workflow.yml'],
        },
    },
    'stackwright-services-otter': {
        'inputs': {
            'artifacts': ['api-config.json', 'workflow-config.json'],
        },
        'outputs': {
            'artifact': 'services-config.json',
        },
    },
    'stackwright-pro-page-otter': {
        'inputs': {
            'sinks': ['_theme.json', '_collections.json', '_auth.json'],
            'artifacts': [
                'design-language.json',
                'data-config.json',
                'services-config.json',
                'geo-manifest.json',
            ],
        },
        'outputs': {
            'artifact': 'pages-manifest.json',
        },
    },
    'stackwright-pro-dashboard-otter': {
        'inputs': {
            'sinks': ['_theme.json', '_collections.json', '_auth.json'],
            'artifacts': [
                'design-language.json',
                'data-config.json',
                'services-config.json',
                'geo-manifest.json',
            ],
        },
        'outputs': {
            'artifact': 'dashboard-manifest.json',
        },
    },
    'stackwright-pro-polish-otter': {
        'inputs': {
            'artifacts': [
                'pages-manifest.json',
                'dashboard-manifest.json',
                'workflow-config.json',
                'auth-config.json',
            ],
        },
        'outputs': {
            'artifact': 'polish-manifest.json',
            'files': ['stackwright.yml'],
        },
    },
}


def add_pipeline(filename_stem: str, declaration: dict) -> None:
    path = os.path.join(SRC_DIR, f'{filename_stem}.json')
    if not os.path.exists(path):
        print(f'    SKIP (not found): {filename_stem}.json')
        return

    with open(path, 'r', encoding='utf-8') as fh:
        data = json.load(fh)

    if 'pipeline' in data:
        print(f'  ⏭  ALREADY HAS pipeline: {filename_stem}.json — overwriting')

    data['pipeline'] = declaration

    serialized = json.dumps(data, indent=2, ensure_ascii=False) + '\n'
    with open(path, 'w', encoding='utf-8') as fh:
        fh.write(serialized)

    print(f'   {filename_stem}.json')


def main() -> None:
    print('Adding pipeline declarations to specialist otter manifests...\n')
    for stem, decl in DECLARATIONS.items():
        add_pipeline(stem, decl)

    print('\nDone. Run `node scripts/generate-checksums.js` to update checksums.json.')


if __name__ == '__main__':
    main()
