"""ADW ZTE Engine — Webhook trigger + pipeline orchestrator.
Built on the factory infrastructure (25 containers, /deploy endpoint, RSI cron)."""
import hashlib
import hmac
import json
import logging
import os
import subprocess
import sys
import time
import urllib.error
import urllib.request
import uuid
from datetime import datetime
from pathlib import Path

BASE = Path(__file__).parent
TREES = BASE / "trees"
MODULES = BASE / "adw_modules"
DEPLOY_URL = os.environ.get("DEPLOY_URL", "http://localhost:8099/deploy")
DEPLOY_TOKEN = os.environ.get("DEPLOY_TOKEN", "factory-deploy-token-2026")

logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
log = logging.getLogger("adw")

def signed_payload(action, target, actor="adw", payload_hash="none"):
    data = {
        "timestamp": int(time.time()),
        "nonce": hashlib.sha256(f"{time.time()}:{target}:{action}".encode()).hexdigest()[:16],
        "actor": actor,
        "action": action,
        "target": target,
        "payload_hash": payload_hash,
    }
    body = json.dumps(data, sort_keys=True, separators=(",", ":")).encode()
    data["signature"] = hmac.new(DEPLOY_TOKEN.encode(), body, hashlib.sha256).hexdigest()
    return data


def post_deploy(payload):
    req = urllib.request.Request(
        DEPLOY_URL,
        data=json.dumps(payload).encode(),
        headers={"Authorization": f"Bearer {DEPLOY_TOKEN}", "Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=15) as r:
            return r.read().decode()[:200]
    except urllib.error.HTTPError as e:
        return e.read().decode()[:200]
    except Exception as e:
        return str(e)[:200]


class ADW:
    def __init__(self, issue=0, title="", body="", zte=False):
        self.id = f"adw-{int(datetime.now().timestamp())}-{uuid.uuid4().hex[:6]}"
        self.issue = issue
        self.title = title or f"ADW {self.id}"
        self.body = body
        self.zte = zte  # uppercase ZTE = auto-ship
        self.phase_results = []

    def classify(self):
        t = (self.title + " " + self.body).lower()
        return "patch" if any(w in t for w in ["bug", "fix", "crash"]) else "feature"

    def run_phase(self, name):
        script = MODULES / f"adw_{name}_iso.py"
        if not script.exists():
            return {"phase": name, "status": "skipped"}
        log.info(f"Phase: {name}")
        r = subprocess.run([
            "python3",
            str(script),
            "--adw-id",
            self.id,
            "--issue",
            str(self.issue),
        ], capture_output=True, text=True, timeout=300)
        return {"phase": name, "status": "ok" if r.returncode == 0 else "fail", "exit": r.returncode}

    def ship(self):
        payload = signed_payload(
            "patch_skill_from_pr",
            self.id,
            payload_hash=hashlib.sha256(f"{self.id}:{self.issue}:{self.title}".encode()).hexdigest()[:16],
        )
        return post_deploy(payload)

    def run(self):
        log.info(f"ADW {self.id} | Issue #{self.issue} | ZTE={'yes' if self.zte else 'no'}")
        _ = self.classify()
        phases = ["plan", "build", "test", "review", "document"]
        for p in phases:
            r = self.run_phase(p)
            self.phase_results.append(r)
            if r["status"] == "fail" and not self.zte:
                break
            if r["status"] == "fail" and self.zte:
                break
        ship_result = None
        all_ok = all(r["status"] == "ok" for r in self.phase_results)
        if all_ok and (self.zte or input("Ship? y/N: ") == "y"):
            ship_result = self.ship()
        return {"id": self.id, "issue": self.issue, "zte": self.zte, "type": self.classify(),
                "phases": self.phase_results, "ship": ship_result}


if __name__ == "__main__":
    import argparse

    a = argparse.ArgumentParser()
    a.add_argument("--issue", type=int, default=0)
    a.add_argument("--title", default="")
    a.add_argument("--zte", action="store_true")
    args = a.parse_args()
    adw = ADW(issue=args.issue, title=args.title, zte=args.zte)
    print(json.dumps(adw.run(), indent=2))
