#!/usr/bin/env bash
set -euo pipefail

: "${CONFIG_CENTER_UPDATES_FILE:?CONFIG_CENTER_UPDATES_FILE is required}"

CONFIG_CENTER_CLUSTERS="${CONFIG_CENTER_CLUSTERS:-ack-dev}"

if [ ! -s "$CONFIG_CENTER_UPDATES_FILE" ]; then
  echo "No config-center image updates were recorded."
  exit 0
fi

if command -v python3 >/dev/null 2>&1; then
  PYTHON=python3
elif command -v python >/dev/null 2>&1; then
  PYTHON=python
else
  echo "Python is required for direct config-center update."
  exit 1
fi

WORKDIR="$(mktemp -d)"
trap 'rm -rf "$WORKDIR"' EXIT

echo "Updating config-center after image build succeeded."
git clone git@git.imall.cloud:im-group/config-center.git "$WORKDIR/config-center"
cd "$WORKDIR/config-center"

"$PYTHON" - "$CONFIG_CENTER_UPDATES_FILE" "$CONFIG_CENTER_CLUSTERS" <<'PY'
from __future__ import annotations

import sys
from pathlib import Path

updates_file = Path(sys.argv[1])
clusters = sys.argv[2].split()
updates = [
    tuple(line.split("|"))
    for line in updates_file.read_text(encoding="utf-8").splitlines()
    if line.strip()
]


def update_file(path: Path, deployment: str, image: str, container: str):
    lines = path.read_text(encoding="utf-8").splitlines(keepends=True)
    changed = False
    matched = False

    def indent_of(line: str) -> int:
        return len(line) - len(line.lstrip(" "))

    doc_starts = [
        idx for idx, line in enumerate(lines) if line.lstrip(" ").startswith("- apiVersion:")
    ]
    doc_starts.append(len(lines))

    for pos, start in enumerate(doc_starts[:-1]):
        end = doc_starts[pos + 1]
        block = lines[start:end]
        if not any(line.lstrip(" ").strip() == "kind: Deployment" for line in block):
            continue

        metadata_idx = next(
            (idx for idx, line in enumerate(block) if line.lstrip(" ").startswith("metadata:")),
            None,
        )
        if metadata_idx is None:
            continue
        metadata_indent = indent_of(block[metadata_idx])
        next_peer = next(
            (
                idx
                for idx in range(metadata_idx + 1, len(block))
                if block[idx].strip() and indent_of(block[idx]) <= metadata_indent
            ),
            len(block),
        )
        metadata = block[metadata_idx:next_peer]
        if not any(
            line.lstrip(" ").startswith("name: ")
            and line.split(":", 1)[1].strip() == deployment
            for line in metadata
        ):
            continue

        list_starts = []
        for idx, line in enumerate(block):
            stripped = line.lstrip(" ")
            if stripped.startswith(("- image:", "- command:", "- name:")):
                list_starts.append(idx)
        list_starts.append(len(block))

        for item_pos, item_start in enumerate(list_starts[:-1]):
            item_end = list_starts[item_pos + 1]
            item = block[item_start:item_end]
            if container and not any(
                line.lstrip(" ").startswith("name: ")
                and line.split(":", 1)[1].strip() == container
                for line in item
            ):
                continue
            for rel_idx, line in enumerate(item):
                stripped = line.lstrip(" ")
                if stripped.startswith("image:") or stripped.startswith("- image:"):
                    matched = True
                    abs_idx = start + item_start + rel_idx
                    old_line = lines[abs_idx]
                    indent = indent_of(old_line)
                    newline = "\n" if old_line.endswith("\n") else ""
                    prefix = old_line[:indent]
                    marker = "- " if old_line.lstrip(" ").startswith("- image:") else ""
                    lines[abs_idx] = f"{prefix}{marker}image: {image}{newline}"
                    changed = changed or lines[abs_idx] != old_line
                    break
            if matched:
                break
        if matched:
            break

    if changed:
        path.write_text("".join(lines), encoding="utf-8")
    return matched, changed


matched_any = False
changed_any = False
for cluster in clusters:
    file = Path("apps/openim/overlays") / cluster / "deployments.yaml"
    if not file.exists():
        raise SystemExit(f"{file} does not exist")
    for deployment, image, container in updates:
        matched, changed = update_file(file, deployment, image, container)
        status = "updated" if changed else "already current" if matched else "no matching change"
        print(f"{cluster}: {deployment} -> {image}: {status}")
        matched_any = matched_any or matched
        changed_any = changed_any or changed

if not matched_any:
    raise SystemExit("no config-center deployment/container matches were found")

if not changed_any:
    print("All matching config-center images are already current.")
PY

if git diff --quiet -- apps/openim/overlays; then
  echo "No config-center image changes to commit."
  exit 0
fi

git config user.name "gitea-actions"
git config user.email "gitea-actions@git.imall.cloud"
git add apps/openim/overlays/*/deployments.yaml
git commit -m "Deploy scheduler-backend image after successful build"
git push origin main
