#!/usr/bin/env python3
from __future__ import annotations
import argparse, hashlib, json, os, pathlib, sys, urllib.request

def read_bundle(source: str) -> dict:
    if source.startswith(("https://","http://")):
        req = urllib.request.Request(
            source,
            headers={
                "User-Agent":"Mozilla/5.0 AXH/1.0",
                "Accept":"application/vnd.ax.harness+json, application/json",
            },
        )
        with urllib.request.urlopen(req, timeout=60) as r:
            return json.loads(r.read().decode("utf-8"))
    return json.loads(pathlib.Path(source).read_text(encoding="utf-8"))

def safe_path(root: pathlib.Path, rel: str) -> pathlib.Path:
    p = pathlib.PurePosixPath(rel)
    if p.is_absolute() or ".." in p.parts:
        raise ValueError(f"unsafe bundle path: {rel}")
    out = (root / pathlib.Path(*p.parts)).resolve()
    if root.resolve() not in out.parents and out != root.resolve():
        raise ValueError(f"path escapes install root: {rel}")
    return out

def install(source: str, dest: str) -> None:
    bundle = read_bundle(source)
    manifest, files = bundle["manifest"], bundle["files"]
    expected = {x["path"]: x["sha256"] for x in manifest.get("files", [])}
    root = pathlib.Path(dest).resolve()
    root.mkdir(parents=True, exist_ok=True)
    for rel, content in files.items():
        raw = str(content).encode("utf-8")
        got = hashlib.sha256(raw).hexdigest()
        if expected.get(rel) != got:
            raise ValueError(f"hash mismatch: {rel}")
        out = safe_path(root, rel)
        out.parent.mkdir(parents=True, exist_ok=True)
        out.write_bytes(raw)
        if out.suffix == ".sh":
            out.chmod(out.stat().st_mode | 0o111)
    print(f"Installed {len(files)} files to {root}")
    print(f"Target: {manifest.get('target')} | Operating profile: {manifest.get('operating_profile_key')}")
    print("No provider/API credentials are embedded. Configure the chosen runtime/model separately.")
    if manifest.get("target") == "openharness-dsh":
        print()
        print("OpenHarness native package detected.")
        print(f'  harness dsh check "{root}"')
        print(f'  harness dsh install "{root}" --link')
        harness_id = None
        try:
            harness_id = json.loads(files.get("harness.json","{}")).get("id")
        except Exception:
            pass
        if harness_id:
            print(f"  harness dsh doctor {harness_id}")

def main():
    p=argparse.ArgumentParser(description="Install an AgencyX/AX .axh harness capsule")
    sub=p.add_subparsers(dest="cmd",required=True)
    i=sub.add_parser("install")
    i.add_argument("source",help=".axh URL or local file")
    i.add_argument("--dir",default=".",help="installation directory")
    a=p.parse_args()
    if a.cmd=="install": install(a.source,a.dir)

if __name__=="__main__":
    main()
