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

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SMOM_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
PROJECT_ROOT="$(cd "$SMOM_ROOT/.." && pwd)"
PROJECT_ENV_LOADER="$PROJECT_ROOT/scripts/lib/load-project-env.sh"
ENV_FILE="$SMOM_ROOT/.env"
ENV_SOURCE="<none>"
RUN_FORGE_DRY_RUN=0
RUN_TIMEOUT_SECONDS="${RUN_TIMEOUT_SECONDS:-90}"
VERBOSITY="${VERBOSITY:--vv}"
EVM_VERSION_CHAIN138="${EVM_VERSION_CHAIN138:-paris}"
export FOUNDRY_PROFILE="${FOUNDRY_PROFILE:-chain138}"

while [[ $# -gt 0 ]]; do
  case "$1" in
    --run)
      RUN_FORGE_DRY_RUN=1
      shift
      ;;
    --timeout-seconds)
      RUN_TIMEOUT_SECONDS="${2:?missing value for --timeout-seconds}"
      shift 2
      ;;
    --verbosity)
      VERBOSITY="${2:?missing value for --verbosity}"
      shift 2
      ;;
    *)
      echo "Unknown argument: $1" >&2
      echo "Usage: $0 [--run] [--timeout-seconds <seconds>] [--verbosity <-v|-vv|-vvv|...>]" >&2
      exit 1
      ;;
  esac
done

CHAIN138_WETH_DEFAULT="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
CHAIN138_USDT_DEFAULT="0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1"
CHAIN138_USDC_DEFAULT="0x71D6687F38b93CCad569Fa6352c876eea967201b"
DAI_PLACEHOLDER_DEFAULT="0x6B175474E89094C44Da98b954EedeAC495271d0F"

if [[ -f "$PROJECT_ENV_LOADER" ]]; then
  export PROJECT_ROOT
  # shellcheck disable=SC1090
  source "$PROJECT_ENV_LOADER"
  ENV_SOURCE="$PROJECT_ENV_LOADER"
elif [[ -f "$ENV_FILE" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$ENV_FILE"
  set +a
  ENV_SOURCE="$ENV_FILE"
fi

RPC_URL_138="${RPC_URL_138:-http://192.168.11.211:8545}"
WETH="${WETH:-$CHAIN138_WETH_DEFAULT}"
OFFICIAL_USDT_ADDRESS="${OFFICIAL_USDT_ADDRESS:-$CHAIN138_USDT_DEFAULT}"
OFFICIAL_USDC_ADDRESS="${OFFICIAL_USDC_ADDRESS:-$CHAIN138_USDC_DEFAULT}"
DAI="${DAI:-$DAI_PLACEHOLDER_DEFAULT}"

missing=()
[[ -n "${PRIVATE_KEY:-}" ]] || missing+=("PRIVATE_KEY")
[[ -n "${RPC_URL_138:-}" ]] || missing+=("RPC_URL_138")

show_var() {
  local name="$1" value="$2" note="${3:-}"
  printf '  %-28s %s' "$name" "$value"
  [[ -n "$note" ]] && printf '  (%s)' "$note"
  printf '\n'
}

probe_bool() {
  local label="$1" token_in="$2" token_out="$3" provider="$4"
  local calldata payload response result
  calldata="$(cast calldata "supportsTokenPair(address,address)" "$token_in" "$token_out" 2>/dev/null || true)"
  [[ -n "$calldata" ]] || {
    echo "  UNKNOWN: $label (failed to encode calldata)"
    return 2
  }
  payload=$(printf '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"%s","data":"%s"},"latest"],"id":1}' "$provider" "$calldata")
  response="$(curl -s -X POST "$RPC_URL_138" -H 'Content-Type: application/json' --data "$payload" 2>/dev/null || true)"
  result="$(printf '%s' "$response" | sed -n 's/.*"result":"\([^"]*\)".*/\1/p')"
  case "$result" in
    "true"|"0x0000000000000000000000000000000000000000000000000000000000000001")
      echo "  OK: $label"
      return 0
      ;;
    "false"|"0x0000000000000000000000000000000000000000000000000000000000000000")
      echo "  MISSING: $label"
      return 1
      ;;
    *)
      echo "  UNKNOWN: $label (provider call failed)"
      return 2
      ;;
  esac
}

run_forge_dry_run() {
  local forge_cmd=(
    forge script script/bridge/trustless/DeployEnhancedSwapRouter.s.sol:DeployEnhancedSwapRouter
    --skip test
    --non-interactive
    --evm-version "$EVM_VERSION_CHAIN138"
    --rpc-url "$RPC_URL_138"
    --private-key "$PRIVATE_KEY"
    "$VERBOSITY"
  )
  local exit_code=0

  set +e
  (
    cd "$SMOM_ROOT" || exit 1
    echo "Running targeted build warm-up"
    command forge build --evm-version "$EVM_VERSION_CHAIN138" contracts/bridge/trustless/EnhancedSwapRouter.sol script/bridge/trustless/DeployEnhancedSwapRouter.s.sol
    echo ""
    echo "Running sourced non-broadcast forge script"
    echo "Working directory: $SMOM_ROOT"
    echo "Timeout: ${RUN_TIMEOUT_SECONDS}s"
    echo "EVM version: $EVM_VERSION_CHAIN138"
    echo "Verbosity: $VERBOSITY"
    echo ""

    if command -v timeout >/dev/null 2>&1; then
      timeout "${RUN_TIMEOUT_SECONDS}s" "${forge_cmd[@]}"
    else
      "${forge_cmd[@]}"
    fi
  )
  exit_code=$?
  set -e

  if (( exit_code == 124 )); then
    echo ""
    echo "Forge dry-run timed out after ${RUN_TIMEOUT_SECONDS}s."
    echo "Likely causes:"
    echo "  - large project compilation still dominates the preflight"
    echo "  - RPC simulation is slow on the current Chain 138 endpoint"
    echo "  - the script needs more visibility to pinpoint the slow phase"
    echo "Next diagnostic step:"
    echo "  bash scripts/deployment/dry-run-enhanced-swap-router-chain138.sh --run --timeout-seconds 180 --verbosity -vvv"
    return 124
  fi

  if (( exit_code != 0 )); then
    echo ""
    echo "Forge dry-run failed with exit code ${exit_code}."
    return "$exit_code"
  fi
}

echo "=== EnhancedSwapRouter Chain 138 Dry Run ==="
echo "Project root: $SMOM_ROOT"
echo "Repository root: $PROJECT_ROOT"
echo "Project env loader: $PROJECT_ENV_LOADER"
echo "Env file: $ENV_FILE"
echo "Env source: $ENV_SOURCE"
echo ""

if (( ${#missing[@]} > 0 )); then
  echo "Missing required env:"
  for item in "${missing[@]}"; do
    echo "  - $item"
  done
  echo ""
  echo "Set them in $ENV_FILE, the repo root env loaded by $PROJECT_ENV_LOADER, or export them in your shell, then rerun."
  exit 1
fi

echo "Required env"
show_var "RPC_URL_138" "$RPC_URL_138" "Core RPC only"
show_var "PRIVATE_KEY" "<set>" "value loaded; not printed"
show_var "FOUNDRY_PROFILE" "$FOUNDRY_PROFILE" "Chain 138 profile defaults to Paris"
show_var "EVM_VERSION_CHAIN138" "$EVM_VERSION_CHAIN138" "Chain 138 Paris hard fork; avoids PUSH0/MCOPY bytecode"
echo ""

echo "Chain 138 token env used by the deploy script"
show_var "WETH" "$WETH" "defaults to Chain 138 canonical WETH"
show_var "OFFICIAL_USDT_ADDRESS" "$OFFICIAL_USDT_ADDRESS" "defaults to Chain 138 mirror USDT"
show_var "OFFICIAL_USDC_ADDRESS" "$OFFICIAL_USDC_ADDRESS" "defaults to Chain 138 mirror USDC"
show_var "DAI" "$DAI" "placeholder unless a real Chain 138 DAI exists"
echo ""

echo "Optional provider env"
show_var "DODOEX_ROUTER" "${DODOEX_ROUTER:-<unset>}" "unset => Dodoex provider disabled after deploy"
show_var "DODO_PMM_PROVIDER_ADDRESS" "${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-<unset>}}" "set => Chain 138 uses deployed PMM provider backend"
show_var "UNISWAP_V3_ROUTER" "${UNISWAP_V3_ROUTER:-<unset>}" "unset => Uniswap provider disabled after deploy"
show_var "CURVE_3POOL" "${CURVE_3POOL:-<unset>}" "unset => Curve provider disabled after deploy"
show_var "BALANCER_VAULT" "${BALANCER_VAULT:-<unset>}" "unset => Balancer provider disabled after deploy"
show_var "ONEINCH_ROUTER" "${ONEINCH_ROUTER:-<unset>}" "unset => 1inch provider disabled after deploy"
echo ""

echo "Live execution readiness"
if [[ -n "${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" ]]; then
  echo "  OK: DODO PMM provider is set, so Chain 138 can use the deployed PMM integration/provider backend."
elif [[ -z "${DODOEX_ROUTER:-}" ]]; then
  echo "  BLOCKER: neither DODOEX_ROUTER nor DODO_PMM_PROVIDER_ADDRESS is set."
  echo "  BLOCKER: live Chain 138 DODO pool mappings would be registered, but no DODO execution path would remain enabled."
else
  echo "  OK: DODOEX_ROUTER is set, so external Dodoex token-to-token execution can stay enabled."
fi
if [[ -z "${UNISWAP_V3_ROUTER:-}" && -z "${BALANCER_VAULT:-}" && -z "${CURVE_3POOL:-}" && -z "${ONEINCH_ROUTER:-}" ]]; then
  echo "  NOTE: no secondary providers are configured yet; that is acceptable for DODO-only bring-up."
fi
echo "  GAP: swapToStablecoin() still needs real WETH -> stable routes before it is operational on Chain 138."
echo ""

if [[ -n "${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" ]] && command -v cast >/dev/null 2>&1; then
  DODO_PROVIDER_TO_PROBE="${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER}}"
  live_pair_missing=0
  echo "Live PMM provider route probe"
  probe_bool "WETH -> OFFICIAL_USDT_ADDRESS" "$WETH" "$OFFICIAL_USDT_ADDRESS" "$DODO_PROVIDER_TO_PROBE" || true
  probe_bool "WETH -> OFFICIAL_USDC_ADDRESS" "$WETH" "$OFFICIAL_USDC_ADDRESS" "$DODO_PROVIDER_TO_PROBE" || true
  probe_bool "WETH -> DAI" "$WETH" "$DAI" "$DODO_PROVIDER_TO_PROBE" || true
  echo "Registered live-pair probe"
  probe_bool "cUSDT -> cUSDC" "0x93E66202A11B1772E55407B32B44e5Cd8eda7f22" "0xf22258f57794CC8E06237084b353Ab30fFfa640b" "$DODO_PROVIDER_TO_PROBE" || true
  if ! probe_bool "cUSDT -> OFFICIAL_USDT_ADDRESS" "0x93E66202A11B1772E55407B32B44e5Cd8eda7f22" "$OFFICIAL_USDT_ADDRESS" "$DODO_PROVIDER_TO_PROBE"; then
    live_pair_missing=1
  fi
  if (( live_pair_missing == 1 )); then
    echo "  BLOCKER: the deployed DODOPMMProvider is missing at least one documented live pair registration."
    echo "  FIX: rerun RegisterDODOPools.s.sol with the corrected 2026-03-26 public pool map."
  fi
  echo "  NOTE: current bridge-and-swap via swapToStablecoin() needs at least one WETH -> stable route above."
  echo ""
fi

echo "Live DODO pairs preloaded by the deploy script"
echo "  - cUSDT <-> cUSDC"
echo "  - cUSDT <-> USDT"
echo "  - cUSDC <-> USDC"
echo "  - cUSDT <-> cXAUC"
echo "  - cUSDC <-> cXAUC"
echo "  - cEURT <-> cXAUC"
echo ""

echo "Exact dry-run command"
if [[ -f "$PROJECT_ENV_LOADER" ]]; then
  echo "cd \"$PROJECT_ROOT/smom-dbis-138\" && source scripts/lib/deployment/dotenv.sh && load_deployment_env --repo-root \"\$PWD/..\" && forge script script/bridge/trustless/DeployEnhancedSwapRouter.s.sol:DeployEnhancedSwapRouter --evm-version \"$EVM_VERSION_CHAIN138\" --rpc-url \"$RPC_URL_138\" --private-key \"\$PRIVATE_KEY\""
else
  echo "cd \"$SMOM_ROOT\" && source .env && forge script script/bridge/trustless/DeployEnhancedSwapRouter.s.sol:DeployEnhancedSwapRouter --evm-version \"$EVM_VERSION_CHAIN138\" --rpc-url \"$RPC_URL_138\" --private-key \"\$PRIVATE_KEY\""
fi
echo ""
echo "Example minimal exports before dry-run"
cat <<EOF
export RPC_URL_138="$RPC_URL_138"
export PRIVATE_KEY='<your-private-key>'
export WETH="$WETH"
export OFFICIAL_USDT_ADDRESS="$OFFICIAL_USDT_ADDRESS"
export OFFICIAL_USDC_ADDRESS="$OFFICIAL_USDC_ADDRESS"
# Optional if a real executable Dodo router exists on Chain 138:
# export DODOEX_ROUTER=0x...
# Preferred on current Chain 138 if DODOPMMProvider is deployed:
# export DODO_PMM_PROVIDER_ADDRESS=0x...
# Optional if/when live on Chain 138:
# export UNISWAP_V3_ROUTER=0x...
# export BALANCER_VAULT=0x...
# export CURVE_3POOL=0x...
# export ONEINCH_ROUTER=0x...
EOF
echo ""
echo "Optional executable preflight"
echo "  bash scripts/deployment/dry-run-enhanced-swap-router-chain138.sh --run"
echo "  bash scripts/deployment/dry-run-enhanced-swap-router-chain138.sh --run --timeout-seconds 180 --verbosity -vvv"
echo ""
echo "Note: this is a safe dry-run helper only. The deploy script still warns that swapToStablecoin() needs real WETH->stable routes to be useful on Chain 138."
echo "Note: Chain 138 is Paris; do not compile Chain 138 deploy bytecode with Cancun/Shanghai opcodes."

if (( RUN_FORGE_DRY_RUN == 1 )); then
  echo ""
  run_forge_dry_run
fi
