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

usage() {
  cat <<'EOF'
Usage:
  validate-cloud-profile.sh --profile <cloud-profile.conf> [options]

Options:
  --profile <path>         Required. Cloud profile file to validate.
  --root <path>            Optional root used to resolve absolute container paths.
  --warn-only              Do not fail on errors; print warnings only.
  --help                   Show this help.

What it checks:
  - Parsable profile rows: EngineName Port Executable [Args...]
  - Port validity and duplicate ports
  - Reserved management port conflict (53350)
  - Executable path existence and execute bit
  - --weights=<path> existence when present
EOF
}

PROFILE=""
ROOT=""
WARN_ONLY=0

while [[ $# -gt 0 ]]; do
  case "$1" in
    --profile)
      PROFILE="${2:-}"
      shift 2
      ;;
    --root)
      ROOT="${2:-}"
      shift 2
      ;;
    --warn-only)
      WARN_ONLY=1
      shift
      ;;
    --help|-h)
      usage
      exit 0
      ;;
    *)
      echo "ERROR: unknown argument: $1" >&2
      usage
      exit 1
      ;;
  esac
done

if [[ -z "${PROFILE}" ]]; then
  echo "ERROR: --profile is required." >&2
  usage
  exit 1
fi

if [[ ! -f "${PROFILE}" ]]; then
  echo "ERROR: profile file not found: ${PROFILE}" >&2
  exit 1
fi

if [[ -n "${ROOT}" && ! -d "${ROOT}" ]]; then
  echo "ERROR: --root directory not found: ${ROOT}" >&2
  exit 1
fi

PROFILE_DIR="$(cd "$(dirname "${PROFILE}")" && pwd)"

PORT_MAP="$(mktemp)"
trap 'rm -f "${PORT_MAP}"' EXIT

ERRORS=0
WARNINGS=0
ROWS=0

warn() {
  WARNINGS=$((WARNINGS + 1))
  echo "WARN: $*" >&2
}

err() {
  if [[ ${WARN_ONLY} -eq 1 ]]; then
    warn "$*"
    return
  fi
  ERRORS=$((ERRORS + 1))
  echo "ERROR: $*" >&2
}

resolve_path() {
  local p="$1"
  if [[ "${p}" == /* ]]; then
    if [[ -n "${ROOT}" ]]; then
      printf '%s' "${ROOT%/}${p}"
    else
      printf '%s' "${p}"
    fi
    return
  fi
  printf '%s' "${PROFILE_DIR}/${p}"
}

validate_weights_args() {
  local args="$1"
  local expanded="${args//:/ }"
  # shellcheck disable=SC2206
  local tokens=( ${expanded} )
  local found=0
  local tok
  for tok in "${tokens[@]}"; do
    if [[ "${tok}" == --weights=* ]]; then
      found=1
      local wp="${tok#--weights=}"
      local wp_resolved
      wp_resolved="$(resolve_path "${wp}")"
      if [[ ! -f "${wp_resolved}" ]]; then
        err "weights file not found: ${wp} (resolved: ${wp_resolved})"
      fi
    fi
  done
  if [[ ${found} -eq 0 ]]; then
    warn "no --weights=... found in args: ${args}"
  fi
}

LINE_NO=0
while IFS= read -r line || [[ -n "${line}" ]]; do
  LINE_NO=$((LINE_NO + 1))
  trimmed="$(echo "${line}" | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//')"
  if [[ -z "${trimmed}" || "${trimmed}" == \#* ]]; then
    continue
  fi

  name="$(echo "${trimmed}" | awk '{print $1}')"
  port="$(echo "${trimmed}" | awk '{print $2}')"
  exe="$(echo "${trimmed}" | awk '{print $3}')"
  args="$(echo "${trimmed}" | awk '{$1=$2=$3=""; sub(/^[ \t]+/, ""); print}')"

  if [[ -z "${name}" || -z "${port}" || -z "${exe}" ]]; then
    err "line ${LINE_NO} is not parsable: ${line}"
    continue
  fi

  ROWS=$((ROWS + 1))

  if ! [[ "${port}" =~ ^[0-9]+$ ]]; then
    err "line ${LINE_NO} has non-numeric port: ${port}"
    continue
  fi
  if (( port < 1 || port > 65535 )); then
    err "line ${LINE_NO} port out of range: ${port}"
  fi
  if [[ "${port}" == "53350" ]]; then
    err "line ${LINE_NO} uses reserved management port 53350"
  fi
  existing_name="$(awk -v p="${port}" -F '\t' '$1 == p {print $2; exit}' "${PORT_MAP}")"
  if [[ -n "${existing_name}" ]]; then
    err "line ${LINE_NO} duplicates port ${port} (already used by ${existing_name})"
  else
    printf '%s\t%s\n' "${port}" "${name}" >> "${PORT_MAP}"
  fi

  exe_resolved="$(resolve_path "${exe}")"
  if [[ ! -f "${exe_resolved}" ]]; then
    err "line ${LINE_NO} executable not found: ${exe} (resolved: ${exe_resolved})"
  elif [[ ! -x "${exe_resolved}" ]]; then
    warn "line ${LINE_NO} executable is not marked executable: ${exe_resolved}"
  fi

  name_lc="$(echo "${name}" | tr '[:upper:]' '[:lower:]')"
  exe_lc="$(echo "${exe}" | tr '[:upper:]' '[:lower:]')"
  if [[ "${name_lc}" == lc0* || "${exe_lc}" == *lc0* ]]; then
    if [[ -n "${args}" ]]; then
      validate_weights_args "${args}"
    else
      warn "line ${LINE_NO} lc0 entry has no args; relies on bridge defaults for weights/backend"
    fi
  fi
done < "${PROFILE}"

echo "Validated ${ROWS} engine entries. warnings=${WARNINGS} errors=${ERRORS}"
if [[ ${ERRORS} -gt 0 ]]; then
  exit 1
fi
exit 0
