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

# 用法说明：
#   适配 run_two_roi_exported_onnx_infer_video_root.sh 的输出目录，对每个 case 执行：
#     {case_dir}/merge.json -> {case_dir}/temporal_observation/stability_report.json
#
# 支持三种模式：
#   1) 批量模式（默认）：遍历 RESULTS_ROOT 下所有包含 merge.json 的 case
#        bash run_two_roi_exported_onnx_temporal_observe_video_root.sh
#   2) 指定根目录模式：第一个参数传推理/跟踪输出根目录
#        bash run_two_roi_exported_onnx_temporal_observe_video_root.sh /path/to/inference_output_root
#   3) 单 case 模式：第一个参数传 case 目录，或直接传 case_dir/merge.json
#        bash run_two_roi_exported_onnx_temporal_observe_video_root.sh /path/to/one_case --track-id 32
#        bash run_two_roi_exported_onnx_temporal_observe_video_root.sh /path/to/one_case/merge.json --track-id 32
#
# 默认读取 merge.json，因为 combined_tracking.json 会给不同 source 的 track_id 加偏移，
# 不利于按单个目标 track_id 做精确筛选。

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
export PYTHONPATH="${PROJECT_ROOT}:${PYTHONPATH:-}"

RESULTS_ROOT="${RESULTS_ROOT:-/data1/dongying/Mono3d/G1M3/test_data/cncap_20260414/20260416103945}"
OUTPUT_ROOT="${OUTPUT_ROOT:-}"
OUTPUT_DIR_NAME="${OUTPUT_DIR_NAME:-temporal_observation}"
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
TEMPORAL_SCRIPT="${TEMPORAL_SCRIPT:-${PROJECT_ROOT}/tools/temporal_analysis/evaluate_temporal_stability.py}"
TRACKING_JSON_NAME="${TRACKING_JSON_NAME:-merge.json}"
TEMPORAL_MIN_LENGTH="${TEMPORAL_MIN_LENGTH:-3}"
TEMPORAL_CLASS_ID="${TEMPORAL_CLASS_ID:-}"
TEMPORAL_TRACK_IDS="${TEMPORAL_TRACK_IDS:-20}"
TEMPORAL_FRAME_ID_START="${TEMPORAL_FRAME_ID_START:-325000}"
TEMPORAL_FRAME_ID_END="${TEMPORAL_FRAME_ID_END:-325200}"
TEMPORAL_PLOTS="${TEMPORAL_PLOTS:-0}"
TEMPORAL_EXPORT_SERIES="${TEMPORAL_EXPORT_SERIES:-1}"
TEMPORAL_FOCUS_TRACK_PLOTS="${TEMPORAL_FOCUS_TRACK_PLOTS:-1}"
TEMPORAL_PREFER_EGO="${TEMPORAL_PREFER_EGO:-1}"
TEMPORAL_X_AXIS="${TEMPORAL_X_AXIS:-frame_id}"
TEMPORAL_HEADING_SOURCE="${TEMPORAL_HEADING_SOURCE:-camera_reg}"

TARGET_PATH="/data1/dongying/Mono3d/G1Q3/dataset_for_evaluation/CNCAP/CSTA_LN_outputs/model_20260416/CSTA-LN_AEB_10_20_20260414141804"
CLI_TRACK_IDS=()
CLI_CLASS_ID=""
CLI_FRAME_ID_START=""
CLI_FRAME_ID_END=""

while (($# > 0)); do
  case "$1" in
    --track-id)
      if (($# < 2)); then
        echo "Error: --track-id requires a value" >&2
        exit 1
      fi
      CLI_TRACK_IDS+=("$2")
      shift 2
      ;;
    --track-id=*)
      CLI_TRACK_IDS+=("${1#*=}")
      shift
      ;;
    --class-id)
      if (($# < 2)); then
        echo "Error: --class-id requires a value" >&2
        exit 1
      fi
      CLI_CLASS_ID="$2"
      shift 2
      ;;
    --class-id=*)
      CLI_CLASS_ID="${1#*=}"
      shift
      ;;
    --frame-id-start)
      if (($# < 2)); then
        echo "Error: --frame-id-start requires a value" >&2
        exit 1
      fi
      CLI_FRAME_ID_START="$2"
      shift 2
      ;;
    --frame-id-start=*)
      CLI_FRAME_ID_START="${1#*=}"
      shift
      ;;
    --frame-id-end)
      if (($# < 2)); then
        echo "Error: --frame-id-end requires a value" >&2
        exit 1
      fi
      CLI_FRAME_ID_END="$2"
      shift 2
      ;;
    --frame-id-end=*)
      CLI_FRAME_ID_END="${1#*=}"
      shift
      ;;
    -*)
      echo "Error: unsupported option: $1" >&2
      exit 1
      ;;
    *)
      if [[ -n "${TARGET_PATH}" ]]; then
        echo "Error: multiple target paths provided: ${TARGET_PATH} and $1" >&2
        exit 1
      fi
      TARGET_PATH="$1"
      shift
      ;;
  esac
done

if [[ -z "${TARGET_PATH}" ]]; then
  TARGET_PATH="${RESULTS_ROOT}"
fi

if [[ ! -e "${TARGET_PATH}" ]]; then
  echo "Error: target path does not exist: ${TARGET_PATH}" >&2
  exit 1
fi

resolve_abs_path() {
  local target_path="$1"
  if [[ -d "${target_path}" ]]; then
    (
      cd "${target_path}"
      pwd -P
    )
    return 0
  fi

  local parent_dir
  parent_dir=$(
    cd "$(dirname "${target_path}")"
    pwd -P
  )
  printf '%s/%s\n' "${parent_dir}" "$(basename "${target_path}")"
}

RESULTS_ROOT_ABS="$(resolve_abs_path "${RESULTS_ROOT}")"

is_case_dir() {
  local dir_path="$1"
  [[ -d "${dir_path}" ]] && [[ -f "${dir_path}/${TRACKING_JSON_NAME}" ]]
}

resolve_case_dir() {
  local target_path="$1"
  if is_case_dir "${target_path}"; then
    printf '%s\n' "${target_path}"
    return 0
  fi
  if [[ -f "${target_path}" ]] && [[ "$(basename "${target_path}")" == "${TRACKING_JSON_NAME}" ]]; then
    dirname "${target_path}"
    return 0
  fi
  return 1
}

derive_output_dir() {
  local case_dir="$1"
  local case_abs
  local rel_case_dir

  case_abs="$(resolve_abs_path "${case_dir}")"
  if [[ -n "${OUTPUT_ROOT}" ]]; then
    if [[ "${case_abs}" == "${RESULTS_ROOT_ABS}" ]]; then
      printf '%s\n' "${OUTPUT_ROOT}"
      return 0
    fi
    if [[ "${case_abs}" == "${RESULTS_ROOT_ABS}"/* ]]; then
      rel_case_dir="${case_abs#"${RESULTS_ROOT_ABS}/"}"
      printf '%s/%s\n' "${OUTPUT_ROOT%/}" "${rel_case_dir}"
      return 0
    fi
    printf '%s/%s\n' "${OUTPUT_ROOT%/}" "$(basename "${case_abs}")"
    return 0
  fi

  printf '%s/%s\n' "${case_abs}" "${OUTPUT_DIR_NAME}"
}

build_track_id_args() {
  local -n out_ref=$1
  out_ref=()

  if [[ "${#CLI_TRACK_IDS[@]}" -gt 0 ]]; then
    for track_id in "${CLI_TRACK_IDS[@]}"; do
      out_ref+=(--track-ids "${track_id}")
    done
    return 0
  fi

  if [[ -n "${TEMPORAL_TRACK_IDS}" ]]; then
    # shellcheck disable=SC2206
    local track_id_arr=(${TEMPORAL_TRACK_IDS})
    for track_id in "${track_id_arr[@]}"; do
      out_ref+=(--track-ids "${track_id}")
    done
  fi
}

run_single_case() {
  local case_dir="$1"
  local tracking_json="${case_dir}/${TRACKING_JSON_NAME}"
  local output_dir
  local cmd
  local track_id_args
  local class_id_value=""
  local frame_id_start_value=""
  local frame_id_end_value=""

  if [[ ! -f "${tracking_json}" ]]; then
    echo "[ERROR] ${TRACKING_JSON_NAME} not found in case directory: ${case_dir}" >&2
    return 1
  fi

  output_dir="$(derive_output_dir "${case_dir}")"
  build_track_id_args track_id_args

  if [[ -n "${CLI_CLASS_ID}" ]]; then
    class_id_value="${CLI_CLASS_ID}"
  elif [[ -n "${TEMPORAL_CLASS_ID}" ]]; then
    class_id_value="${TEMPORAL_CLASS_ID}"
  fi

  if [[ -n "${CLI_FRAME_ID_START}" ]]; then
    frame_id_start_value="${CLI_FRAME_ID_START}"
  elif [[ -n "${TEMPORAL_FRAME_ID_START}" ]]; then
    frame_id_start_value="${TEMPORAL_FRAME_ID_START}"
  fi

  if [[ -n "${CLI_FRAME_ID_END}" ]]; then
    frame_id_end_value="${CLI_FRAME_ID_END}"
  elif [[ -n "${TEMPORAL_FRAME_ID_END}" ]]; then
    frame_id_end_value="${TEMPORAL_FRAME_ID_END}"
  fi

  cmd=(
    "${PYTHON_BIN}" "${TEMPORAL_SCRIPT}"
    --input "${tracking_json}"
    --output "${output_dir}/stability_report.json"
    --min-length "${TEMPORAL_MIN_LENGTH}"
    --x-axis "${TEMPORAL_X_AXIS}"
    --heading-source "${TEMPORAL_HEADING_SOURCE}"
  )

  if [[ -n "${class_id_value}" ]]; then
    cmd+=(--class-id "${class_id_value}")
  fi

  if [[ -n "${frame_id_start_value}" ]]; then
    cmd+=(--frame-id-start "${frame_id_start_value}")
  fi

  if [[ -n "${frame_id_end_value}" ]]; then
    cmd+=(--frame-id-end "${frame_id_end_value}")
  fi

  if [[ "${#track_id_args[@]}" -gt 0 ]]; then
    cmd+=("${track_id_args[@]}")
  fi

  if [[ "${TEMPORAL_PLOTS}" == "1" ]]; then
    cmd+=(--plots)
  fi

  if [[ "${TEMPORAL_EXPORT_SERIES}" == "1" ]]; then
    cmd+=(--export-series)
  fi

  if [[ "${TEMPORAL_FOCUS_TRACK_PLOTS}" == "1" ]]; then
    cmd+=(--focus-track-plots)
  fi

  if [[ "${TEMPORAL_PREFER_EGO}" == "1" ]]; then
    cmd+=(--prefer-ego)
  else
    cmd+=(--no-prefer-ego)
  fi

  echo ""
  echo "######################################################################"
  echo "# Exported video-root temporal observation"
  echo "######################################################################"
  echo "Case   : ${case_dir}"
  echo "Track  : ${tracking_json}"
  echo "Output : ${output_dir}"
  if [[ -n "${class_id_value}" ]]; then
    echo "Class  : ${class_id_value}"
  fi
  if [[ -n "${frame_id_start_value}" || -n "${frame_id_end_value}" ]]; then
    echo "Frame ID Range: [${frame_id_start_value:-"-inf"}, ${frame_id_end_value:-"+inf"}]"
  fi
  echo "Heading Source: ${TEMPORAL_HEADING_SOURCE}"
  if [[ "${#CLI_TRACK_IDS[@]}" -gt 0 ]]; then
    echo "Track IDs: ${CLI_TRACK_IDS[*]}"
  elif [[ -n "${TEMPORAL_TRACK_IDS}" ]]; then
    echo "Track IDs: ${TEMPORAL_TRACK_IDS}"
  fi

  "${cmd[@]}"
}

run_batch_root() {
  local batch_root="$1"
  local total_cases=0
  local success_cases=0
  local failed_cases=0

  while IFS= read -r -d '' tracking_json; do
    local case_dir
    case_dir="$(dirname "${tracking_json}")"
    ((total_cases += 1))

    if run_single_case "${case_dir}"; then
      ((success_cases += 1))
    else
      ((failed_cases += 1))
      printf '[FAIL] case=%s\n' "${case_dir}" >&2
    fi
  done < <(
    find "${batch_root}" -type f -name "${TRACKING_JSON_NAME}" -print0 | sort -z
  )

  if [[ "${total_cases}" -eq 0 ]]; then
    echo "[ERROR] No ${TRACKING_JSON_NAME} files were found under: ${batch_root}" >&2
    return 1
  fi

  echo ""
  printf '[DONE] cases=%d success=%d failed=%d\n' \
    "${total_cases}" "${success_cases}" "${failed_cases}"

  [[ "${failed_cases}" -eq 0 ]]
}

if RESOLVED_CASE_DIR="$(resolve_case_dir "${TARGET_PATH}")"; then
  run_single_case "${RESOLVED_CASE_DIR}"
elif [[ -d "${TARGET_PATH}" ]]; then
  run_batch_root "${TARGET_PATH}"
else
  echo "Error: unsupported target path: ${TARGET_PATH}" >&2
  exit 1
fi
