import { readFileSync } from "node:fs";

const key = process.argv[2] || "";
const input = JSON.parse(readFileSync(0, "utf8"));

function cleanMap(value) {
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
  const out = {};
  for (const [k, v] of Object.entries(value)) {
    if (k === "kubectl.kubernetes.io/last-applied-configuration") continue;
    out[k] = v;
  }
  return out;
}

function metadata(obj) {
  return {
    name: obj?.metadata?.name || null,
    namespace: obj?.metadata?.namespace || null,
    labels: cleanMap(obj?.metadata?.labels),
    annotations: cleanMap(obj?.metadata?.annotations),
  };
}

function compactContainer(container) {
  return {
    name: container?.name || null,
    image: container?.image || null,
    env: Array.isArray(container?.env)
      ? container.env.filter((item) => item && typeof item.name === "string" && typeof item.value === "string").map((item) => ({ name: item.name, value: item.value }))
      : [],
  };
}

function condition(obj, type) {
  const conditions = Array.isArray(obj?.status?.conditions) ? obj.status.conditions : [];
  return conditions.find((item) => item?.type === type) || conditions[0] || null;
}

function timestampMs(value) {
  const parsed = Date.parse(String(value || ""));
  return Number.isFinite(parsed) ? parsed : null;
}

function durationSeconds(start, end) {
  const s = timestampMs(start);
  const e = timestampMs(end);
  return s === null || e === null || e < s ? null : Math.round((e - s) / 1000);
}

let output = input;
if (key === "pipelineRun") {
  const succeeded = condition(input, "Succeeded");
  output = {
    apiVersion: input.apiVersion,
    kind: input.kind,
    metadata: metadata(input),
    spec: {
      pipelineRef: { name: input?.spec?.pipelineRef?.name || null },
      params: Array.isArray(input?.spec?.params) ? input.spec.params : [],
    },
    status: {
      conditions: Array.isArray(input?.status?.conditions) ? input.status.conditions : [],
      startTime: input?.status?.startTime || null,
      completionTime: input?.status?.completionTime || null,
      durationSeconds: durationSeconds(input?.status?.startTime, input?.status?.completionTime),
      succeeded: succeeded?.status || null,
      reason: succeeded?.reason || null,
    },
  };
} else if (key === "pipeline") {
  const tasks = Array.isArray(input?.spec?.tasks) ? input.spec.tasks : [];
  const runtimeReady = tasks.find((item) => item?.name === "runtime-ready") || null;
  const gitopsPromote = tasks.find((item) => item?.name === "gitops-promote") || null;
  const gitopsResults = Array.isArray(gitopsPromote?.taskSpec?.results) ? gitopsPromote.taskSpec.results : [];
  output = {
    apiVersion: input.apiVersion,
    kind: input.kind,
    metadata: {
      name: input?.metadata?.name || null,
      namespace: input?.metadata?.namespace || null,
      annotations: {
        sourceConfig: input?.metadata?.annotations?.["hwlab.pikastech.local/source-config"] || null,
        ciContract: input?.metadata?.annotations?.["hwlab.pikastech.local/ci-contract"] || null,
        policy: input?.metadata?.annotations?.["hwlab.pikastech.local/policy"] || null,
      },
    },
    spec: {
      taskCount: tasks.length,
      runtimeReadyTask: {
        present: runtimeReady !== null,
        name: runtimeReady?.name || null,
        runAfter: Array.isArray(runtimeReady?.runAfter) ? runtimeReady.runAfter.slice(0, 6) : [],
        when: Array.isArray(runtimeReady?.when)
          ? runtimeReady.when.slice(0, 4).map((item) => ({
              input: item?.input || null,
              operator: item?.operator || null,
              values: Array.isArray(item?.values) ? item.values.slice(0, 6) : [],
            }))
          : [],
      },
      gitopsPromoteTask: {
        present: gitopsPromote !== null,
        name: gitopsPromote?.name || null,
        resultNames: gitopsResults
          .map((item) => item?.name || null)
          .filter((item) => typeof item === "string")
          .slice(0, 8),
        runtimeReadyRequiredResult: gitopsResults.some((item) => item?.name === "runtime-ready-required"),
      },
    },
  };
} else if (key === "taskRuns") {
  const items = (Array.isArray(input?.items) ? input.items : []).map((item) => {
    const succeeded = condition(item, "Succeeded");
    return {
      name: item?.metadata?.name || null,
      namespace: item?.metadata?.namespace || null,
      pipelineTask: item?.metadata?.labels?.["tekton.dev/pipelineTask"] || item?.metadata?.labels?.["tekton.dev/task"] || null,
      status: succeeded?.status || null,
      reason: succeeded?.reason || null,
      startTime: item?.status?.startTime || null,
      completionTime: item?.status?.completionTime || null,
      durationSeconds: durationSeconds(item?.status?.startTime, item?.status?.completionTime),
    };
  }).sort((left, right) => String(left.startTime || "").localeCompare(String(right.startTime || "")));
  const slow = items.filter((item) => typeof item.durationSeconds === "number" && item.durationSeconds > 60);
  output = {
    ok: true,
    count: items.length,
    succeededCount: items.filter((item) => item.status === "True").length,
    failedCount: items.filter((item) => item.status === "False").length,
    activeCount: items.filter((item) => item.status !== "True" && item.status !== "False").length,
    items,
    performance: { slowCount: slow.length, slowTaskRuns: slow.slice(0, 8), warning: slow.length > 0 ? "taskrun-over-60s" : null },
    statusAuthority: "kubernetes-api-serviceaccount",
  };
} else if (key === "argoApplication") {
  const resources = Array.isArray(input?.status?.resources) ? input.status.resources : [];
  const syncResultResources = Array.isArray(input?.status?.operationState?.syncResult?.resources)
    ? input.status.operationState.syncResult.resources
        .filter(problemSyncResource)
        .slice(0, 8)
        .map((item) => ({
          group: item.group || null,
          kind: item.kind || null,
          namespace: item.namespace || null,
          name: item.name || null,
          status: item.status || null,
          hookPhase: item.hookPhase || null,
          syncPhase: item.syncPhase || null,
          message: item.message || null,
        }))
    : [];
  const nonReadyResources = resources
    .filter((item) => item?.health?.status && item.health.status !== "Healthy")
    .slice(0, 8)
    .map((item) => ({
      kind: item.kind || null,
      namespace: item.namespace || null,
      name: item.name || null,
      status: item.status || null,
      healthStatus: item.health?.status || null,
      healthMessage: item.health?.message || null,
    }));
  output = {
    apiVersion: input.apiVersion,
    kind: input.kind,
    metadata: metadata(input),
    status: {
      sync: input?.status?.sync || null,
      health: input?.status?.health || null,
      conditions: Array.isArray(input?.status?.conditions)
        ? input.status.conditions.slice(0, 8).map((item) => ({ type: item.type || null, message: item.message || null, lastTransitionTime: item.lastTransitionTime || null }))
        : [],
      nonReadyResources,
      operationState: input?.status?.operationState
        ? {
            phase: input.status.operationState.phase || null,
            message: input.status.operationState.message || null,
            startedAt: input.status.operationState.startedAt || null,
            finishedAt: input.status.operationState.finishedAt || null,
            durationSeconds: durationSeconds(input.status.operationState.startedAt, input.status.operationState.finishedAt),
            syncResultResources,
          }
        : null,
    },
  };
} else if (/^workload\d+$/.test(key)) {
  const template = input?.spec?.template || {};
  output = {
    apiVersion: input.apiVersion,
    kind: input.kind,
    metadata: metadata(input),
    spec: {
      replicas: input?.spec?.replicas ?? null,
      template: {
        metadata: { labels: cleanMap(template?.metadata?.labels), annotations: cleanMap(template?.metadata?.annotations) },
        spec: { containers: Array.isArray(template?.spec?.containers) ? template.spec.containers.map(compactContainer) : [] },
      },
    },
    status: {
      replicas: input?.status?.replicas ?? null,
      readyReplicas: input?.status?.readyReplicas ?? null,
      availableReplicas: input?.status?.availableReplicas ?? null,
      updatedReplicas: input?.status?.updatedReplicas ?? null,
      conditions: Array.isArray(input?.status?.conditions) ? input.status.conditions.map((item) => ({ type: item.type || null, status: item.status || null, reason: item.reason || null })) : [],
    },
  };
}

console.log(JSON.stringify(output));

function problemSyncResource(item) {
  const message = String(item?.message || "");
  return (item?.status && item.status !== "Synced")
    || (item?.hookPhase && item.hookPhase !== "Succeeded")
    || /fail|error|backoff|forbidden|invalid|denied|exceeded/iu.test(message);
}
