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

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
DEFAULT_COZY_VERSION="$(tr -d '[:space:]' < "$REPO_ROOT/versions/cozy-version.conf")"
DEFAULT_CNCF_VERSION="$(tr -d '[:space:]' < "$REPO_ROOT/versions/cncf-version.conf")"
DEFAULT_CNCF_SERVER_PORT="$(tr -d '[:space:]' < "$REPO_ROOT/versions/cncf-server-port.conf")"
DEFAULT_CORE_VERSION="$(tr -d '[:space:]' < "$REPO_ROOT/versions/goldenport-core-version.conf")"
DEFAULT_SIMPLEMODELING_MODEL_VERSION="$(tr -d '[:space:]' < "$REPO_ROOT/versions/simplemodeling-model-version.conf")"
DEFAULT_SBT_COZY_VERSION="$(tr -d '[:space:]' < "$REPO_ROOT/versions/sbt-cozy-version.conf")"
usage() {
  cat <<'EOF'
Usage:
  bin/setup
  bin/setup bootstrap
  bin/setup cozy [--cozy-version <version>] [--sbt-cozy-version <version>]
  bin/setup cncf [--cncf-version <version>] [--cncf-server-port <port>] [--core-version <version>] [--simplemodeling-model-version <version>]
  bin/setup textus
  bin/setup all

Current responsibilities:
  - verify the installed cozy launcher used by bin/cozy and sbt-cozy delegates
  - verify the coursier-installed cncf command used directly by samples
  - verify the optional textus launcher used for packaged Textus applications
  - report the configured runtime dependency versions used by sample validation

Install/update stable launchers:
  cs install --force cozy --channel https://www.simplemodeling.org/repository/cozy/coursier-channel.json
  cs install --force cncf --channel https://www.simplemodeling.org/repository/textus/coursier-channel.json
  cs install --force textus --channel https://www.simplemodeling.org/repository/textus/coursier-channel.json
EOF
}

cozy_version="${COZY_VERSION:-$DEFAULT_COZY_VERSION}"
cncf_version="${CNCF_VERSION:-$DEFAULT_CNCF_VERSION}"
cncf_server_port="${CNCF_SERVER_PORT:-$DEFAULT_CNCF_SERVER_PORT}"
core_version="${GOLDENPORT_CORE_VERSION:-$DEFAULT_CORE_VERSION}"
simplemodeling_model_version="${SIMPLEMODELING_MODEL_VERSION:-$DEFAULT_SIMPLEMODELING_MODEL_VERSION}"
sbt_cozy_version="${SBT_COZY_VERSION:-$DEFAULT_SBT_COZY_VERSION}"

canonical_path() {
  local path="$1"
  local dir
  dir="$(cd "$(dirname "$path")" && pwd -P)"
  printf '%s/%s\n' "$dir" "$(basename "$path")"
}

find_installed_cncf() {
  if [[ -n "${CNCF_COMMAND:-}" ]]; then
    printf '%s\n' "$CNCF_COMMAND"
    return
  fi
  local candidate=""
  candidate="$(command -v cncf || true)"
  if [[ -n "$candidate" ]]; then
    local self candidate_path
    self="$(canonical_path "$REPO_ROOT/bin/cncf")"
    candidate_path="$(canonical_path "$candidate")"
    if [[ "$candidate_path" != "$self" ]]; then
      printf '%s\n' "$candidate"
      return
    fi
  fi
  return 1
}


find_installed_cozy() {
  if [[ -n "${COZY_COMMAND:-}" ]]; then
    printf '%s\n' "$COZY_COMMAND"
    return
  fi
  local candidate=""
  candidate="$(command -v cozy || true)"
  if [[ -n "$candidate" ]]; then
    local self candidate_path
    self="$(canonical_path "$REPO_ROOT/bin/cozy")"
    candidate_path="$(canonical_path "$candidate")"
    if [[ "$candidate_path" != "$self" ]]; then
      printf '%s\n' "$candidate"
      return
    fi
  fi
  return 1
}

find_installed_textus() {
  if [[ -n "${TEXTUS_COMMAND:-}" ]]; then
    printf '%s\n' "$TEXTUS_COMMAND"
    return
  fi
  command -v textus || return 1
}

prepare_cozy() {
  local cozy_bin
  if ! cozy_bin="$(find_installed_cozy)"; then
    echo "installed cozy launcher not found" >&2
    echo "Install or expose it on PATH, or set COZY_COMMAND=/path/to/cozy." >&2
    exit 3
  fi
  "$cozy_bin" help >/dev/null
  if [[ -n "${COZY_PROJECT_DIR:-}" ]]; then
    local classpath_file="${COZY_CLASSPATH_FILE:-$COZY_PROJECT_DIR/target/classpath.txt}"
    if [[ ! -f "$classpath_file" ]]; then
      echo "cozy source classpath file not found: $classpath_file" >&2
      echo "Run: cd $COZY_PROJECT_DIR && sbt compile exportClasspath" >&2
      exit 3
    fi
  fi
  local runtime_current
  runtime_current="$("$cozy_bin" runtime current)"
  echo "cozy command: $cozy_bin"
  echo "cozy version: $cozy_version"
  echo "cozy launcher: $("$cozy_bin" launcher version)"
  echo "cozy runtime current: $runtime_current"
  echo "sbt-cozy version: $sbt_cozy_version"
  if [[ "$runtime_current" != "$cozy_version" ]]; then
    echo "warning: recommended cozy runtime is $cozy_version but launcher current is $runtime_current" >&2
  fi
  if [[ -f "$REPO_ROOT/.cozy/launcher.yaml" ]]; then
    echo "cozy workspace config: $REPO_ROOT/.cozy/launcher.yaml"
  fi
  if [[ -n "${COZY_PROJECT_DIR:-}" ]]; then
    echo "cozy project dir: $COZY_PROJECT_DIR"
  fi
}
prepare_cncf() {
  if ! command -v java >/dev/null 2>&1; then
    echo "java command not found" >&2
    exit 3
  fi
  local cncf_bin
  if ! cncf_bin="$(find_installed_cncf)"; then
    echo "installed cncf command not found" >&2
    echo "Install it with coursier:" >&2
    echo "  cs install --force cncf --channel https://www.simplemodeling.org/repository/textus/coursier-channel.json" >&2
    echo "If needed, set CNCF_COMMAND=/path/to/cncf." >&2
    exit 3
  fi
  "$cncf_bin" --help >/dev/null
  local runtime_current
  runtime_current="$("$cncf_bin" runtime current)"
  echo "java: $(command -v java)"
  echo "cncf command: $cncf_bin"
  echo "cncf version: $cncf_version"
  echo "cncf launcher: $("$cncf_bin" launcher version)"
  echo "cncf runtime current: $runtime_current"
  echo "cncf server port: $cncf_server_port"
  echo "goldenport-core version: $core_version"
  echo "simplemodeling-model version: $simplemodeling_model_version"
  if [[ "$runtime_current" != "$cncf_version" ]]; then
    echo "warning: recommended cncf runtime is $cncf_version but launcher current is $runtime_current" >&2
  fi
  if [[ -f "$REPO_ROOT/.cncf/launcher.yaml" ]]; then
    echo "cncf workspace config: $REPO_ROOT/.cncf/launcher.yaml"
  fi
}

prepare_textus() {
  local textus_bin
  if ! textus_bin="$(find_installed_textus)"; then
    echo "installed textus command not found" >&2
    echo "Install it with coursier:" >&2
    echo "  cs install --force textus --channel https://www.simplemodeling.org/repository/textus/coursier-channel.json" >&2
    echo "If needed, set TEXTUS_COMMAND=/path/to/textus." >&2
    exit 3
  fi
  "$textus_bin" --help >/dev/null
  local runtime_current
  runtime_current="$("$textus_bin" runtime current)"
  echo "textus command: $textus_bin"
  echo "textus launcher: $("$textus_bin" launcher version)"
  echo "textus runtime current: $runtime_current"
  if [[ -f "$REPO_ROOT/.textus/config.yaml" ]]; then
    echo "textus workspace config: $REPO_ROOT/.textus/config.yaml"
  fi
}

main() {
  local mode="${1:-bootstrap}"
  if [[ $# -gt 0 ]]; then
    shift
  fi
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --cozy-version)
        cozy_version="${2:-}"
        shift 2
        ;;
      --cozy-version=*)
        cozy_version="${1#--cozy-version=}"
        shift
        ;;
      --sbt-cozy-version)
        sbt_cozy_version="${2:-}"
        shift 2
        ;;
      --sbt-cozy-version=*)
        sbt_cozy_version="${1#--sbt-cozy-version=}"
        shift
        ;;
      --cncf-version)
        cncf_version="${2:-}"
        shift 2
        ;;
      --cncf-version=*)
        cncf_version="${1#--cncf-version=}"
        shift
        ;;
      --core-version)
        core_version="${2:-}"
        shift 2
        ;;
      --cncf-server-port)
        cncf_server_port="${2:-}"
        shift 2
        ;;
      --cncf-server-port=*)
        cncf_server_port="${1#--cncf-server-port=}"
        shift
        ;;
      --core-version=*)
        core_version="${1#--core-version=}"
        shift
        ;;
      --simplemodeling-model-version)
        simplemodeling_model_version="${2:-}"
        shift 2
        ;;
      --simplemodeling-model-version=*)
        simplemodeling_model_version="${1#--simplemodeling-model-version=}"
        shift
        ;;
      *)
        usage >&2
        exit 1
        ;;
    esac
  done

  case "$mode" in
    cncf)
      prepare_cncf
      ;;
    textus)
      prepare_textus
      ;;
    cozy)
      prepare_cozy
      ;;
    bootstrap)
      prepare_cozy
      prepare_cncf
      ;;
    all)
      prepare_cozy
      prepare_cncf
      prepare_textus
      ;;
    -h|--help|help)
      usage
      ;;
    *)
      usage >&2
      exit 1
      ;;
  esac
}

main "$@"
