#!/bin/sh
set +e

tmpdir=$(mktemp -d)
cleanup() { rm -rf "${tmpdir}"; }
trap cleanup EXIT INT TERM

script_dir="${NATIVE_CICD_SCRIPT_DIR}"
repo_path="${REPO_PATH}"
branch="${SOURCE_BRANCH}"
repository="${REPOSITORY}"
snapshot_prefix="${SNAPSHOT_PREFIX}"
gitops_branch="${GITOPS_BRANCH:-}"
tekton_namespace="${TEKTON_NAMESPACE:-}"
pipeline_run_prefix="${PIPELINE_RUN_PREFIX:-}"
argo_namespace="${ARGO_NAMESPACE:-}"
argo_application="${ARGO_APPLICATION:-}"

emit_file_b64() {
  key="$1"
  path="$2"
  printf 'UNIDESK_NATIVE_JSON\t%s\t' "${key}"
  base64 "${path}" | tr -d '\n'
  printf '\n'
}

emit_error_b64() {
  key="$1"
  path="$2"
  printf 'UNIDESK_NATIVE_ERROR\t%s\t' "${key}"
  base64 "${path}" | tr -d '\n'
  printf '\n'
}

emit_kube_json() {
  key="$1"
  path="$2"
  raw="${tmpdir}/${key}.raw"
  out="${tmpdir}/${key}.out"
  err="${tmpdir}/${key}.err"
  if node "${script_dir}/kube-get.mjs" "${path}" >"${raw}" 2>"${err}" && node "${script_dir}/compact-native-object.mjs" "${key}" <"${raw}" >"${out}" 2>>"${err}"; then
    emit_file_b64 "${key}" "${out}"
  else
    emit_error_b64 "${key}" "${err}"
  fi
}

emit_plan_artifacts() {
  namespace="$1"
  pipeline_run="$2"
  out="${tmpdir}/planArtifacts.out"
  err="${tmpdir}/planArtifacts.err"
  if node "${script_dir}/plan-artifacts.mjs" "${namespace}" "${pipeline_run}" >"${out}" 2>"${err}"; then
    emit_file_b64 planArtifacts "${out}"
  else
    emit_error_b64 planArtifacts "${err}"
  fi
}

source_commit=
source_err="${tmpdir}/source.err"
if [ -x /etc/unidesk-cicd-branch-follower/sync-source.sh ]; then
  /etc/unidesk-cicd-branch-follower/sync-source.sh "${repository}" "${branch}" "${snapshot_prefix}" "${repo_path}" >/dev/null 2>"${source_err}" || true
fi

if [ -d "${repo_path}/objects" ]; then
  source_commit=$(git --git-dir="${repo_path}" rev-parse --verify "refs/heads/${branch}^{commit}" 2>>"${source_err}" | head -n 1 | tr -d '\r' || true)
else
  printf 'formal controller/job must mount k8s git-mirror cache at %s; fallback exec is disabled\n' "${repo_path}" >>"${source_err}"
fi

case "${source_commit}" in
  [0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])
    stage_ref="${snapshot_prefix%/}/${source_commit}"
    source_out="${tmpdir}/source.out"
    printf '{"commit":"%s","branch":"%s","stageRef":"%s","sourceAuthority":"k8s-git-mirror-snapshot","mode":"k8s-git-mirror-cache","repoPath":"%s"}' "${source_commit}" "${branch}" "${stage_ref}" "${repo_path}" >"${source_out}"
    emit_file_b64 source "${source_out}"
    ;;
  *)
    emit_error_b64 source "${source_err}"
    ;;
esac

if [ -d "${repo_path}/objects" ]; then
  git_mirror_out="${tmpdir}/gitMirror.out"
  git_mirror_err="${tmpdir}/gitMirror.err"
  if REPO_PATH="${repo_path}" REPOSITORY="${repository}" SOURCE_BRANCH="${branch}" SNAPSHOT_PREFIX="${snapshot_prefix}" GITOPS_BRANCH="${gitops_branch}" node "${script_dir}/compact-git-mirror.mjs" >"${git_mirror_out}" 2>"${git_mirror_err}"; then
    emit_file_b64 gitMirror "${git_mirror_out}"
  else
    emit_error_b64 gitMirror "${git_mirror_err}"
  fi
fi

if [ -n "${source_commit}" ] && [ -n "${tekton_namespace}" ] && [ -n "${pipeline_run_prefix}" ]; then
  pipeline_runs_raw="${tmpdir}/pipelineRuns.raw"
  pipeline_run_raw="${tmpdir}/pipelineRun.raw"
  pipeline_run_out="${tmpdir}/pipelineRun.out"
  pipeline_run_err="${tmpdir}/pipelineRun.err"
  if node "${script_dir}/kube-get.mjs" "/apis/tekton.dev/v1/namespaces/${tekton_namespace}/pipelineruns" >"${pipeline_runs_raw}" 2>"${pipeline_run_err}" \
    && node "${script_dir}/select-current-pipelinerun.mjs" "${source_commit}" "${pipeline_run_prefix}" <"${pipeline_runs_raw}" >"${pipeline_run_raw}" 2>>"${pipeline_run_err}" \
    && node "${script_dir}/compact-native-object.mjs" pipelineRun <"${pipeline_run_raw}" >"${pipeline_run_out}" 2>>"${pipeline_run_err}"; then
    emit_file_b64 pipelineRun "${pipeline_run_out}"
  else
    emit_error_b64 pipelineRun "${pipeline_run_err}"
  fi
  pipeline_run="$(node -e "const fs=require('node:fs'); try { const value=JSON.parse(fs.readFileSync(process.argv[1], 'utf8')); process.stdout.write(value?.metadata?.name || ''); } catch {}" "${pipeline_run_raw}" 2>/dev/null || true)"
  pipeline_ref="$(node -e "const fs=require('node:fs'); try { const value=JSON.parse(fs.readFileSync(process.argv[1], 'utf8')); process.stdout.write(value?.spec?.pipelineRef?.name || ''); } catch {}" "${tmpdir}/pipelineRun.raw" 2>/dev/null || true)"
  if [ -n "${pipeline_ref}" ]; then
    emit_kube_json pipeline "/apis/tekton.dev/v1/namespaces/${tekton_namespace}/pipelines/${pipeline_ref}"
  fi
  if [ -n "${pipeline_run}" ]; then
    emit_kube_json taskRuns "/apis/tekton.dev/v1/namespaces/${tekton_namespace}/taskruns?labelSelector=tekton.dev%2FpipelineRun%3D${pipeline_run}"
    emit_plan_artifacts "${tekton_namespace}" "${pipeline_run}"
  fi
fi

if [ -n "${argo_namespace}" ] && [ -n "${argo_application}" ]; then
  emit_kube_json argoApplication "/apis/argoproj.io/v1alpha1/namespaces/${argo_namespace}/applications/${argo_application}"
fi

if [ -n "${WORKLOAD_REFS_B64:-}" ]; then
  printf '%s' "${WORKLOAD_REFS_B64}" | base64 -d | while IFS="$(printf '\t')" read -r key path; do
    [ -n "${key}" ] || continue
    [ -n "${path}" ] || continue
    emit_kube_json "${key}" "${path}"
  done
fi

exit 0
