#!/bin/sh
set -eu
# __HWLAB_DEPENDENCY_PROXY_PROBE__
echo '{"event":"ci-base-image","phase":"poller","image":"__HWLAB_CI_TOOLS_IMAGE__","policy":"no-runtime-apk"}'
for tool in node git ssh curl timeout; do command -v "$tool" >/dev/null 2>&1 || { echo '{"event":"ci-base-image","phase":"poller","ok":false,"reason":"missing-tool","tool":"'"$tool"'"}'; exit 31; }; done
# __HWLAB_GIT_SSH_SHELL__

git_ssh_setup
workdir="$(mktemp -d)"
git_timed poller-clone 180 git clone --depth 1 --branch "$SOURCE_BRANCH" "$GIT_READ_URL" "$workdir/repo"
cd "$workdir/repo"
git remote set-url origin "$GIT_READ_URL"
revision="$(git rev-parse HEAD)"
subject="$(git log -1 --pretty=%s)"
case "$subject" in
  "chore: promote node GitOps source "*)
    echo "Skipping generated GitOps promotion commit $revision"
    exit 0
    ;;
esac
short="$(printf '%.12s' "$revision")"
: "${PIPELINERUN_PREFIX:?PIPELINERUN_PREFIX is required}"
: "${GITOPS_TARGET:?GITOPS_TARGET is required}"
prefix="$PIPELINERUN_PREFIX"
name="$prefix-$short"
export POLLER_REVISION="$revision"
export POLLER_PIPELINERUN="$name"
export POLLER_SOURCE_SUBJECT="$subject"
echo "Checking $GITOPS_TARGET source $revision with PipelineRun $name"
node <<'NODE'
const fs = require("node:fs");
const https = require("node:https");

function requiredEnv(name) {
  const value = process.env[name];
  if (!value) throw new Error(name + " is required");
  return value;
}

function optionalEnv(name) {
  return process.env[name] || "";
}

const namespace = requiredEnv("POD_NAMESPACE");
const name = requiredEnv("POLLER_PIPELINERUN");
const revision = requiredEnv("POLLER_REVISION");
const host = process.env.KUBERNETES_SERVICE_HOST;
const port = process.env.KUBERNETES_SERVICE_PORT || "443";
if (!host) throw new Error("KUBERNETES_SERVICE_HOST is not available");

const token = fs.readFileSync("/var/run/secrets/kubernetes.io/serviceaccount/token", "utf8");
const ca = fs.readFileSync("/var/run/secrets/kubernetes.io/serviceaccount/ca.crt");

function request(method, path, body) {
  const payload = body ? JSON.stringify(body) : "";
  const headers = { Authorization: "Bearer " + token };
  if (payload) {
    headers["Content-Type"] = "application/json";
    headers["Content-Length"] = Buffer.byteLength(payload);
  }
  return new Promise((resolve, reject) => {
    const req = https.request({ host, port, method, path, ca, headers }, (res) => {
      let data = "";
      res.setEncoding("utf8");
      res.on("data", (chunk) => { data += chunk; });
      res.on("end", () => resolve({ statusCode: res.statusCode || 0, body: data }));
    });
    req.on("error", reject);
    if (payload) req.write(payload);
    req.end();
  });
}

const labels = {
  "app.kubernetes.io/part-of": "hwlab",
  "hwlab.pikastech.local/gitops-target": requiredEnv("GITOPS_TARGET"),
  "hwlab.pikastech.local/source-commit": revision,
  "hwlab.pikastech.local/trigger": "polling"
};

const pipelineRun = {
  apiVersion: "tekton.dev/v1",
  kind: "PipelineRun",
  metadata: {
    name,
    namespace,
    labels,
    annotations: {
      "hwlab.pikastech.local/source-subject": optionalEnv("POLLER_SOURCE_SUBJECT"),
      "hwlab.pikastech.local/source-branch": requiredEnv("SOURCE_BRANCH"),
      "hwlab.pikastech.local/gitops-branch": requiredEnv("GITOPS_BRANCH")
    }
  },
  spec: {
    pipelineRef: { name: requiredEnv("PIPELINE_NAME") },
    taskRunTemplate: {
      serviceAccountName: requiredEnv("SERVICE_ACCOUNT_NAME"),
      podTemplate: { hostNetwork: true, dnsPolicy: "ClusterFirstWithHostNet", securityContext: { fsGroup: 1000 } }
    },
    params: [
      { name: "git-url", value: requiredEnv("GIT_URL") },
      { name: "git-read-url", value: requiredEnv("GIT_READ_URL") },
      { name: "source-branch", value: requiredEnv("SOURCE_BRANCH") },
      { name: "gitops-branch", value: requiredEnv("GITOPS_BRANCH") },
      { name: "lane", value: requiredEnv("LANE") },
      { name: "catalog-path", value: requiredEnv("CATALOG_PATH") },
      { name: "image-tag-mode", value: requiredEnv("IMAGE_TAG_MODE") },
      { name: "runtime-path", value: requiredEnv("RUNTIME_PATH") },
      { name: "revision", value: revision },
      { name: "registry-prefix", value: requiredEnv("REGISTRY_PREFIX") },
      { name: "services", value: requiredEnv("SERVICES") },
      { name: "base-image", value: requiredEnv("BASE_IMAGE") }
    ],
    workspaces: [
      { name: "source", volumeClaimTemplate: { spec: { accessModes: ["ReadWriteOnce"], resources: { requests: { storage: "8Gi" } } } } },
      { name: "git-ssh", secret: { secretName: "hwlab-git-ssh" } }
    ]
  }
};

const base = "/apis/tekton.dev/v1/namespaces/" + encodeURIComponent(namespace) + "/pipelineruns";
const item = base + "/" + encodeURIComponent(name);

(async () => {
  const existing = await request("GET", item);
  if (existing.statusCode === 200) {
    console.log(JSON.stringify({ status: "exists", pipelineRun: name, revision }));
    return;
  }
  if (existing.statusCode !== 404) {
    throw new Error("unexpected PipelineRun lookup status " + existing.statusCode + ": " + existing.body.slice(0, 500));
  }
  const created = await request("POST", base, pipelineRun);
  if (created.statusCode < 200 || created.statusCode > 299) {
    throw new Error("PipelineRun create failed with status " + created.statusCode + ": " + created.body.slice(0, 1000));
  }
  console.log(JSON.stringify({ status: "created", pipelineRun: name, revision }));
})().catch((error) => {
  console.error(error.stack || error.message);
  process.exitCode = 1;
});
NODE
