"use strict";
const crypto = require("node:crypto");
const fs = require("node:fs");
const path = require("node:path");
const { validateDeploymentSource } = require("./deployment-source-policy");

// A push can request deployment, but it can never execute deployment itself.
// The separate resident deployment agent consumes these immutable event files.
function enqueueDeploymentEvent(intent, push, queueDir, context = {}) {
  if (!intent) return { state: "not_requested" };
  const invalid = validateIntent(intent, push, context);
  if (invalid) return { state: "rejected", diagnostic_code: invalid };
  fs.mkdirSync(queueDir, { recursive: true, mode: 0o750 });
  const event = {
    schema: "guanghu.deployment-event/v1",
    event_id: crypto.randomUUID(),
    created_at: Date.now() / 1000,
    state: "queued_for_resident_agent",
    repo: push.repo, branch: push.branch, commit_sha: push.commit_sha,
    workorder_id: String(intent.workorder_id || ""),
    resource: intent.resource, action: "provision-approved-architecture",
    manifest: intent.manifest,
    authorizer_id: String(context.authorizer_id || ""),
    persona_id: String(context.persona_id || ""),
    execution_runtime_id: String(context.execution_runtime_id || ""),
    target: String(context.target || ""),
    deployment_source: intent.deployment_source || null,
  };
  const target = path.join(queueDir, `${event.created_at}-${event.event_id}.json`);
  const temporary = `${target}.${process.pid}.tmp`;
  fs.writeFileSync(temporary, JSON.stringify(event), { mode: 0o640 });
  fs.renameSync(temporary, target);
  return { state: event.state, event_id: event.event_id };
}
function validateIntent(intent, push, context = {}) {
  if (intent.schema !== "guanghu.deployment-intent/v1") return "deployment_intent_schema_invalid";
  if (String(intent.repo || "").toLowerCase() !== push.repo || intent.branch !== push.branch || String(intent.commit_sha || "").toLowerCase() !== push.commit_sha) return "deployment_intent_binding_mismatch";
  const resource = String(intent.resource || "").match(/^([A-Z0-9][A-Z0-9._-]{5,119})@([0-9a-f]{40})$/);
  if (!resource || resource[2] !== push.commit_sha) return "deployment_intent_resource_invalid";
  if (!/^deployment\/requests\/[A-Za-z0-9._/-]{1,180}\.json$/.test(String(intent.manifest || ""))) return "deployment_intent_manifest_invalid";
  if (intent.manifest !== `deployment/requests/${resource[1]}.json`) return "deployment_intent_manifest_resource_mismatch";
  if (context.registry) {
    return validateDeploymentSource({
      repo: push.repo,
      authorizer_id: String(context.authorizer_id || ""),
      persona_id: String(context.persona_id || ""),
      execution_runtime_id: String(context.execution_runtime_id || ""),
      target: String(context.target || ""),
      deployment_source: intent.deployment_source || null,
    }, context.registry);
  }
  return "";
}
module.exports = { enqueueDeploymentEvent, validateIntent };
