#!/usr/bin/env bash
# Deploy to all mainnets: CCIP Bridge, Trustless Bridge, Oracle, Mapper, PMM (anchored to ChainID 138).
# Run after check-balances-gas-and-deploy.sh. Requires .env with PRIVATE_KEY and per-chain RPC/CCIP vars.
# Usage: bash scripts/deployment/deploy-all-mainnets-with-mapper-oracle-pmm.sh [phase]
#   phase: ccip | trustless | oracle | mapper | pmm | all (default: all)

set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
FORGE_SCOPE_RUNNER=(bash "$PROJECT_ROOT/scripts/forge/scope.sh")
# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source.
if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then
  # shellcheck disable=SC1090
  source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
  load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}"
elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$PROJECT_ROOT/.env"
  set +a
elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$REPO_ROOT/.env"
  set +a
fi

# Load .env without strict unset (avoid init.sh pipefail on .env)
[ -f "$SCRIPT_DIR/../lib/infura.sh" ] && source "$SCRIPT_DIR/../lib/infura.sh"

PHASE="${1:-all}"
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

require_env() {
  local var="$1"
  if [ -z "${!var:-}" ]; then
    echo -e "${RED}ERROR: $var not set in .env${NC}" >&2
    return 1
  fi
  return 0
}

ensure_rpc() {
  local rpc="$1"
  type ensure_infura_rpc_url &>/dev/null && [ -n "$rpc" ] && rpc=$(ensure_infura_rpc_url "$rpc")
  echo "$rpc"
}

# --- CCIP: DeployAll to BSC, Polygon, Base, Optimism, Gnosis ---
run_ccip_remaining_mainnets() {
  echo -e "${YELLOW}=== CCIP Bridges (DeployAll) to BSC, Polygon, Base, Optimism, Gnosis ===${NC}"
  require_env PRIVATE_KEY || return 1
  local chains="BSC:56:BSC_RPC_URL POLYGON:137:POLYGON_MAINNET_RPC BASE:8453:BASE_MAINNET_RPC OPTIMISM:10:OPTIMISM_MAINNET_RPC GNOSIS:100:GNOSIS_MAINNET_RPC"
  for entry in $chains; do
    local name="${entry%%:*}"; entry="${entry#*:}"
    local chain_id="${entry%%:*}"; entry="${entry#*:}"
    local rpc_var="$entry"
    local rpc="${!rpc_var:-}"
    rpc=$(ensure_rpc "$rpc")
    if [ -z "$rpc" ]; then
      echo "  Skip $name (no RPC)"
      continue
    fi
    echo -e "${YELLOW}DeployAll to $name (chain $chain_id)...${NC}"
    "${FORGE_SCOPE_RUNNER[@]}" script script/DeployAll.s.sol:DeployAll \
      --rpc-url "$rpc" --chain-id "$chain_id" --private-key "$PRIVATE_KEY" \
      --broadcast --slow -vvv || echo -e "${RED}$name DeployAll failed${NC}"
    echo ""
  done
  echo -e "${GREEN}CCIP phase done.${NC}"
}

# --- Trustless Bridge: Chain 138 (Lockbox) + Ethereum (BondManager, etc.) ---
run_trustless() {
  echo -e "${YELLOW}=== Trustless Bridge (Chain 138 + Ethereum) ===${NC}"
  require_env PRIVATE_KEY RPC_URL_138 || return 1
  echo "Deploying Trustless (Lockbox) on Chain 138..."
  "${FORGE_SCOPE_RUNNER[@]}" script script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge \
    --rpc-url "$RPC_URL_138" --broadcast --via-ir --private-key "$PRIVATE_KEY" -vvv || true
  require_env ETHEREUM_MAINNET_RPC || return 1
  MAINNET_RPC=$(ensure_rpc "$ETHEREUM_MAINNET_RPC")
  echo "Deploying Trustless (BondManager, ChallengeManager, LP, Inbox, SwapRouter, Coordinator) on Ethereum..."
  "${FORGE_SCOPE_RUNNER[@]}" script script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge \
    --rpc-url "$MAINNET_RPC" --broadcast --via-ir --private-key "$PRIVATE_KEY" \
    ${ETHERSCAN_API_KEY:+--verify --etherscan-api-key "$ETHERSCAN_API_KEY"} -vvv || true
  echo -e "${GREEN}Trustless phase done.${NC}"
}

# --- Oracle: Chain 138 ---
run_oracle() {
  echo -e "${YELLOW}=== Oracle (Chain 138) ===${NC}"
  require_env PRIVATE_KEY RPC_URL_138 || return 1
  "${FORGE_SCOPE_RUNNER[@]}" script script/DeployOracle.s.sol:DeployOracle \
    --rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" \
    --with-gas-price "${GAS_PRICE_138:-1000000000}" --legacy -vvv || true
  echo -e "${GREEN}Oracle phase done.${NC}"
}

# --- Mapper: Chain 138 (full) + others (empty) ---
run_mapper() {
  echo -e "${YELLOW}=== Mapper (Chain 138 = AddressMapper; others = AddressMapperEmpty) ===${NC}"
  require_env PRIVATE_KEY || return 1
  if [ -n "${RPC_URL_138:-}" ]; then
    echo "Deploying AddressMapper on Chain 138..."
    "${FORGE_SCOPE_RUNNER[@]}" script script/DeployAddressMapper.s.sol:DeployAddressMapper \
      --rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" \
      --with-gas-price "${GAS_PRICE_138:-1000000000}" --legacy -vvv || true
  fi
  local chains="ETHEREUM_MAINNET_RPC:1 BSC_RPC_URL:56 POLYGON_MAINNET_RPC:137 BASE_MAINNET_RPC:8453 ARBITRUM_MAINNET_RPC:42161 OPTIMISM_MAINNET_RPC:10 AVALANCHE_RPC_URL:43114 CRONOS_RPC_URL:25 GNOSIS_MAINNET_RPC:100"
  for entry in $chains; do
    local rpc_var="${entry%%:*}"; local chain_id="${entry#*:}"
    local rpc="${!rpc_var:-}"
    [ -z "$rpc" ] && continue
    rpc=$(ensure_rpc "$rpc")
    echo "Deploying AddressMapperEmpty on chain $chain_id..."
    "${FORGE_SCOPE_RUNNER[@]}" script script/DeployAddressMapperOtherChain.s.sol:DeployAddressMapperOtherChain \
      --rpc-url "$rpc" --chain-id "$chain_id" --broadcast --private-key "$PRIVATE_KEY" -vvv || true
  done
  echo -e "${GREEN}Mapper phase done.${NC}"
}

# --- PMM (DODO) on Chain 138 ---
run_pmm() {
  echo -e "${YELLOW}=== PMM Liquidity Pools (Chain 138) ===${NC}"
  require_env PRIVATE_KEY RPC_URL_138 || return 1
  if [ -z "${DODO_PMM_INTEGRATION:-}" ] && [ -n "${DODO_VENDING_MACHINE_ADDRESS:-}" ]; then
    echo "Deploying DODOPMMIntegration on Chain 138..."
    "${FORGE_SCOPE_RUNNER[@]}" script script/dex/DeployDODOPMMIntegration.s.sol:DeployDODOPMMIntegration \
      --rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" \
      --with-gas-price "${GAS_PRICE_138:-1000000000}" --legacy -vvv || true
  else
    echo "  DODOPMMIntegration already set or DODO_VENDING_MACHINE_ADDRESS not set; skip deploy."
  fi
  if [ -n "${DODO_PMM_INTEGRATION:-}" ] && [ -n "${XAU_ADDRESS:-}" ]; then
    echo "Creating XAU-anchored pools..."
    "${FORGE_SCOPE_RUNNER[@]}" script script/dex/DeployPrivatePoolRegistryAndPools.s.sol:DeployPrivatePoolRegistryAndPools \
      --rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" \
      --with-gas-price "${GAS_PRICE_138:-1000000000}" --legacy -vvv || true
  fi
  echo -e "${GREEN}PMM phase done.${NC}"
}

# --- Main ---
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}All Mainnets: CCIP, Trustless, Oracle, Mapper, PMM${NC}"
echo -e "${GREEN}========================================${NC}"
echo "Phase: $PHASE"
echo ""

case "$PHASE" in
  ccip)     run_ccip_remaining_mainnets ;;
  trustless) run_trustless ;;
  oracle)   run_oracle ;;
  mapper)   run_mapper ;;
  pmm)      run_pmm ;;
  all)
    run_ccip_remaining_mainnets
    run_trustless
    run_oracle
    run_mapper
    run_pmm
    ;;
  *) echo "Usage: $0 [ccip|trustless|oracle|mapper|pmm|all]"; exit 1 ;;
esac

echo ""
echo -e "${GREEN}Done. Update .env and config/smart-contracts-master.json with any new addresses.${NC}"
