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

# ============================================================
#  Config & Defaults
# ============================================================
tag_default="master"
dst_default="./tidb-ng-dashboards/v9.0.x"
tmp_default="./tmp"

# ============================================================
#  main: parse args, clone optionally, update titles, cleanup
# ============================================================
main() {
  local tag="${1:-$tag_default}"
  local dst="${2:-$dst_default}"
  local tmp="$tmp_default"
  local skip_clone=false

  # Parse optional flags (e.g., --skip-clone)
  for arg in "$@"; do
    if [[ "$arg" == "--skip-clone" ]]; then
      skip_clone=true
    fi
  done

  mkdir -p "$dst" "$tmp"

  if [ "$skip_clone" = false ]; then
    echo "Cloning and collecting dashboards into: $dst"

    # Function to clone or pull repository
    clone_or_pull() {
      local repo_url="$1"
      local branch="$2"
      local target_dir="$3"
      local repo_name="$4"

      if [ -d "$target_dir" ]; then
        echo "Updating existing $repo_name repository..."
        cd "$target_dir"
        git fetch origin
        git checkout "$branch"
        git pull origin "$branch"
        cd - >/dev/null
      else
        echo "Cloning $repo_name repository..."
        git clone --depth 1 -b "$branch" "$repo_url" "$target_dir"
      fi
    }

    clone_or_pull "https://github.com/pingcap/tidb.git" "master" "$tmp/tidb" "tidb"
    cp "$tmp/tidb/pkg/metrics/nextgengrafana/"*.json "$dst/" || true

    clone_or_pull "https://github.com/tidbcloud/cloud-storage-engine.git" "cloud-engine" "$tmp/tikv" "tikv"
    cp "$tmp/tikv/metrics/grafana/"*.json "$dst/" || true

    clone_or_pull "https://github.com/tikv/pd.git" "$tag" "$tmp/pd" "pd"
    cp "$tmp/pd/metrics/grafana/"*.json "$dst/" || true

    clone_or_pull "https://github.com/pingcap/tiflash.git" "master" "$tmp/tiflash" "tiflash"
    cp "$tmp/tiflash/metrics/grafana/"*.json "$dst/" || true

    clone_or_pull "https://github.com/pingcap/TiProxy.git" "main" "$tmp/TiProxy" "TiProxy"
    cp "$tmp/TiProxy/pkg/metrics/grafana/tiproxy_summary.json" "$dst/" || true

    clone_or_pull "https://github.com/pingcap/ticdc.git" "master" "$tmp/ticdc" "ticdc"
    cp "$tmp/ticdc/metrics/nextgengrafana/"*.json "$dst/" || true

    echo "Dashboard JSONs collected."
  else
    echo "Skipping clone & collect (using existing JSON files in: $dst)"
  fi

  echo "Updating top-level dashboard titles in: $dst"
  update_dashboard_titles "$dst"

  echo "Filtering out excluded dashboards from: $dst"
  filter_dashboards "$dst"

  if [ "$skip_clone" = false ]; then
    rm -rf "$tmp"
    echo "Temporary directory removed: $tmp"
  fi

  echo "Done. Dashboards available in: $dst"
}

# ============================================================
#  Function: update_dashboard_titles
#  Purpose : Add [Logic]/[Physic] prefixes to top-level titles
#           (skips already-tagged titles)
# ============================================================
update_dashboard_titles() {
  local dir="$1"
  shopt -s nullglob
  local found=0

  for f in "$dir"/*.json; do
    found=1

    # Dashboard JSON uses two-space indentation for top-level fields. Match
    # only that title so panel titles cannot be mistaken for the dashboard.
    local title
    title=$(sed -n 's/^  "title": *"\([^"]*\)".*/\1/p' "$f" | tail -1)
    [[ -z "$title" ]] && continue

    # Skip if already tagged
    if [[ "$title" == \[*UserScope\]* || "$title" == \[*SharedScope\]* ]]; then
      continue
    fi

    # Locate the exact line number of that last title occurrence
    local lineno
    lineno=$(grep -nF "\"title\": \"$title\"" "$f" | tail -1 | cut -d: -f1 || true)
    [[ -z "${lineno:-}" ]] && continue

    # Build new title
    local new
    if [[ "$title" == *KeyspaceName* ]]; then
      if [[ "$title" == *-KeyspaceName ]]; then
        new="[UserScope]${title%-KeyspaceName}"
      else
        new="[UserScope]$title"
      fi
    else
      new="[SharedScope]$title"
    fi

    # Replace safely (mktemp works on macOS/BSD and Linux)
    local tmpf
    tmpf=$(mktemp)
    local new_escaped=${new//\//\\/}

    sed "${lineno}s/\"title\"[[:space:]]*:[[:space:]]*\"[^\"]*\"/\"title\": \"${new_escaped}\"/" "$f" >"$tmpf" &&
      mv "$tmpf" "$f" &&
      echo "Updated: $f — '$title' → '$new'" ||
      echo "Failed: $f"
  done

  shopt -u nullglob
  if [[ $found -eq 0 ]]; then
    echo "WARNING: No JSON files found in \"$dir\"."
  fi
}

# ============================================================
#  Function: filter_dashboards
#  Purpose : Remove dashboards matching exclude patterns
# ============================================================
filter_dashboards() {
  local dir="$1"

  local removed_count=0

  # Remove each excluded file if it exists
  local excluded_files=(
    "tikv_raw.json"
    "tikv_details_serverless.json"
    "tikv_trouble_shooting.json"
    "tikv_summary.json"
    "overview.json"
    "overview_with_keyspace_name.json"
    "tidb_summary_with_keyspace_name.json"
    "tiflash_proxy_summary.json"
  )

  for file in "${excluded_files[@]}"; do
    local filepath="$dir/$file"
    if [[ -f "$filepath" ]]; then
      rm -f "$filepath"
      echo "Removed: $file"
      removed_count=$((removed_count + 1))
    fi
  done

  if [[ $removed_count -eq 0 ]]; then
    echo "INFO: No dashboards matched exclude patterns."
  else
    echo "Removed $removed_count dashboard(s)."
  fi
}

# --- entrypoint (call main after all functions are defined) ---
main "$@"
