#!/usr/bin/env python3
"""Verify AI Upgrade cloud offers and local screenshot-check insertion support."""

from __future__ import annotations

import hashlib
import json
import os
import subprocess
import tempfile
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
RUNTIME = ROOT / "bin" / "carbon-runtime"


def run(environment: dict[str, str], *args: str, ok: bool = True) -> subprocess.CompletedProcess[str]:
    result = subprocess.run([str(RUNTIME), "ai-upgrade", *args], cwd=ROOT, env=environment, text=True, capture_output=True)
    if ok and result.returncode:
        raise AssertionError(result.stderr or result.stdout)
    if not ok and result.returncode == 0:
        raise AssertionError("Expected AI Upgrade command to fail closed")
    return result


skill = (ROOT / "skills" / "ai-upgrade" / "SKILL.md").read_text(encoding="utf-8")
reference = (ROOT / "runtime" / "carbon" / "references" / "ai-upgrade-visual-checks.md").read_text(encoding="utf-8")
settings = (ROOT / "ui" / "settings.html").read_text(encoding="utf-8")
server = (ROOT / "server" / "index.js").read_text(encoding="utf-8")
for phrase in (
    "aiUpgradeOptions", "testers_propose_tests", "ai-upgrade inspect", "1–3 checkpoints", "install-helper",
    "apply_patch", "fail-on critical", "on-error warn", "never embed an API key", "Open the CARBON report",
):
    assert phrase in skill, f"AI Upgrade skill missing {phrase}"
for phrase in ("One check per distinct risk state", "screenshot-only provenance", "deterministic test failures remain authoritative", "no-shell process API"):
    assert phrase in reference, f"AI visual-check reference missing {phrase}"
for identifier in ("ai-provider", "ai-model", "ai-api-key", "ai-key-state", "clear-ai-key"):
    assert f'id="{identifier}"' in settings, f"settings missing {identifier}"
assert "AI_PROVIDER_ENV" in server and "aiUpgradeOptions" in server and "aiApiKeyConfigured" in server

with tempfile.TemporaryDirectory(prefix="carbon-ai-upgrade-") as temporary:
    workspace = Path(temporary)
    home = workspace / "home"
    project = workspace / "project"
    tests = project / "tests"
    tests.mkdir(parents=True)
    (home / ".config" / "carbon").mkdir(parents=True)
    (home / ".config" / "carbon" / "config.json").write_text(json.dumps({"aiProvider": "openai", "aiModel": "contract-vision-model"}), encoding="utf-8")
    playwright = tests / "checkout.spec.ts"
    playwright.write_text("""import { test, expect } from '@playwright/test';
test('checkout success', async ({ page }) => {
  await page.goto('/checkout');
  await expect(page.getByText('Order confirmed')).toBeVisible();
  await page.screenshot({ path: 'artifacts/checkout.png' });
});
""", encoding="utf-8")
    cypress = tests / "settings.cy.js"
    cypress.write_text("describe('settings', () => { it('saves', () => { cy.visit('/settings'); cy.contains('Saved').should('be.visible'); }); });\n", encoding="utf-8")
    selenium = tests / "test_profile.py"
    selenium.write_text("from selenium import webdriver\n\ndef test_profile(driver):\n    driver.get('/profile')\n    assert driver.find_element('id', 'profile').is_displayed()\n", encoding="utf-8")
    environment = dict(os.environ)
    environment.update({"HOME": str(home), "CARBON_CREDENTIAL_STORE": "file"})
    for variable in ("OPENAI_API_KEY", "ANTHROPIC_API_KEY", "GEMINI_API_KEY", "CARBON_AI_API_KEY", "TESTERS_AI_API_KEY"):
        environment.pop(variable, None)
    before = hashlib.sha256(playwright.read_bytes()).hexdigest()
    inspected = json.loads(run(environment, "inspect", "--root", str(project)).stdout)
    assert inspected["schema"] == "carbon.ai-upgrade-inspection/v1"
    assert set(inspected["frameworks"]) == {"playwright", "cypress", "selenium"}, inspected["frameworks"]
    assert inspected["candidateCount"] >= 6
    assert inspected["localAiScreenshotReview"]["model"] == "contract-vision-model"
    assert inspected["localAiScreenshotReview"]["keyValueReturned"] is False
    assert inspected["cloudEnrichment"]["mutatesCloud"] is False
    assert hashlib.sha256(playwright.read_bytes()).hexdigest() == before

    denied = run(environment, "install-helper", "--root", str(project), "--provider", "openai", "--model", "contract-vision-model", ok=False)
    assert "--confirm" in denied.stderr and not (project / ".carbon" / "upgrade").exists()
    installed = json.loads(run(environment, "install-helper", "--root", str(project), "--provider", "openai", "--model", "contract-vision-model", "--confirm").stdout)
    assert installed["installed"] is True and installed["keyStoredInProject"] is False
    helper = Path(installed["helperPath"])
    helper_text = helper.read_text(encoding="utf-8")
    assert "contract-vision-model" not in helper_text and "OPENAI_API_KEY" in helper_text
    config = json.loads(Path(installed["configPath"]).read_text(encoding="utf-8"))
    assert config["failOn"] == "critical" and config["onError"] == "warn"
    image = workspace / "checkpoint.png"
    image.write_bytes(b"contract-image-placeholder")
    dry = subprocess.run(["python3", str(helper), "--image", str(image), "--name", "checkout", "--dry-run"], env=environment, text=True, capture_output=True)
    assert dry.returncode == 0
    dry_payload = json.loads(dry.stdout)
    assert dry_payload["model"] == "contract-vision-model" and dry_payload["keyValueReturned"] is False

print("PASS: AI Upgrade key-aware route selection, smart checkpoint inspection, approval gate, provider-neutral helper, dry run, and no-key-in-source contract verified.")
