#!/usr/bin/env bash
# Deploy LINK Token Contract on ChainID 138
# This script deploys a standard ERC20 LINK token contract
# Usage: ./deploy-link-token.sh

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
source "$PROJECT_ROOT/scripts/lib/address-inventory.sh"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

load_explorer_runtime_env

# Configuration
RPC_URL="${RPC_URL_138:-http://192.168.11.250:8545}"
EXPECTED_LINK_ADDRESS="$(resolve_address_value LINK_TOKEN LINK_TOKEN 0x326C977E6efc84E512bB9C30f76E30c160eD06FB)"

if [ -z "${PRIVATE_KEY:-}" ]; then
    log_error "PRIVATE_KEY not available in effective environment"
    exit 1
fi

DEPLOYER=$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || echo "")
if [ -z "$DEPLOYER" ]; then
    log_error "Could not derive address from PRIVATE_KEY"
    exit 1
fi

log_info "========================================="
log_info "Deploy LINK Token Contract"
log_info "========================================="
log_info ""
log_info "Network: ChainID 138"
log_info "RPC: $RPC_URL"
log_info "Deployer: $DEPLOYER"
log_info "Expected Address: $EXPECTED_LINK_ADDRESS"
log_info ""

# Check if contract already exists
log_info "Checking if LINK token already exists..."
EXISTING_CODE=$(cast code "$EXPECTED_LINK_ADDRESS" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
if [ -n "$EXISTING_CODE" ] && [ "$EXISTING_CODE" != "0x" ]; then
    log_warn "Contract already exists at $EXPECTED_LINK_ADDRESS"
    log_info "Checking if it's a valid ERC20 token..."
    
    # Try to call standard ERC20 functions
    NAME=$(cast call "$EXPECTED_LINK_ADDRESS" "name()" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
    SYMBOL=$(cast call "$EXPECTED_LINK_ADDRESS" "symbol()" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
    
    if [ -n "$NAME" ] && [ -n "$SYMBOL" ]; then
        log_success "✓ Valid ERC20 token found!"
        log_info "  Name: $NAME"
        log_info "  Symbol: $SYMBOL"
        log_info ""
        log_info "No deployment needed. Contract is already deployed."
        exit 0
    else
        log_warn "Contract exists but doesn't appear to be a valid ERC20 token"
        log_info "Proceeding with deployment to expected address..."
    fi
fi

# Check if we need to use CREATE2 for deterministic address
log_info ""
log_info "Note: To deploy to the expected address ($EXPECTED_LINK_ADDRESS),"
log_info "you may need to use CREATE2 with specific salt, or deploy to a"
log_info "different address and update configurations."
log_info ""

# Create temporary contract file
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT

log_info "Creating LINK token contract..."
cat > "$TEMP_DIR/LinkToken.sol" << 'EOF'
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract LinkToken is ERC20 {
    constructor() ERC20("Chainlink Token", "LINK") {
        // Initial supply: 1 billion LINK (1,000,000,000 * 10^18)
        _mint(msg.sender, 1_000_000_000 * 10**18);
    }
}
EOF

log_info "Contract source created at: $TEMP_DIR/LinkToken.sol"
log_info ""
log_warn "⚠️  This script requires Foundry and OpenZeppelin contracts"
log_warn "⚠️  For production, use the official Chainlink LINK token contract"
log_warn "⚠️  This is a simplified ERC20 implementation"
log_info ""

# Check if forge is available
if ! command -v forge &> /dev/null; then
    log_error "Foundry (forge) is not installed"
    log_info "Install Foundry: https://book.getfoundry.sh/getting-started/installation"
    log_info ""
    log_info "Alternative: Deploy using Remix IDE or Hardhat"
    log_info "Contract source saved to: $TEMP_DIR/LinkToken.sol"
    exit 1
fi

# Check if source project exists
SOURCE_PROJECT="/home/intlc/projects/smom-dbis-138"
if [ ! -d "$SOURCE_PROJECT" ]; then
    log_warn "Source project not found: $SOURCE_PROJECT"
    log_info "Creating minimal Foundry project for deployment..."
    
    cd "$TEMP_DIR"
    forge init --no-git --force . > /dev/null 2>&1 || true
    
    # Install OpenZeppelin
    forge install OpenZeppelin/openzeppelin-contracts --no-git --no-commit > /dev/null 2>&1 || true
    
    # Copy contract
    mkdir -p src
    cp LinkToken.sol src/
    
    log_info "Minimal project created"
    DEPLOY_DIR="$TEMP_DIR"
else
    log_info "Using source project: $SOURCE_PROJECT"
    cd "$SOURCE_PROJECT"
    
    # Check if MockLinkToken exists
    if [ -f "contracts/tokens/MockLinkToken.sol" ]; then
        log_info "Found MockLinkToken contract, using it instead"
        USE_MOCK=true
    else
        USE_MOCK=false
        # Copy contract to source project if needed
        if [ ! -f "contracts/LinkToken.sol" ]; then
            mkdir -p contracts
            cp "$TEMP_DIR/LinkToken.sol" contracts/
            log_info "Contract copied to source project"
        fi
    fi
    DEPLOY_DIR="$SOURCE_PROJECT"
fi

# Deploy contract
log_info ""
log_info "Deploying LINK token contract..."
log_info "This may take a few minutes..."

# Get optimal gas price
if [ -f "$SCRIPT_DIR/get-optimal-gas-from-api.sh" ]; then
    OPTIMAL_GAS=$("$SCRIPT_DIR/get-optimal-gas-from-api.sh" "proposed" 2>/dev/null || echo "")
    if [ -z "$OPTIMAL_GAS" ] || [ "$OPTIMAL_GAS" = "0" ]; then
        CURRENT_GAS=$(cast gas-price --rpc-url "$RPC_URL" 2>/dev/null || echo "1000000000")
        OPTIMAL_GAS=$(echo "scale=0; $CURRENT_GAS * 1.5 / 1" | bc 2>/dev/null || echo "$CURRENT_GAS")
    fi
else
    CURRENT_GAS=$(cast gas-price --rpc-url "$RPC_URL" 2>/dev/null || echo "1000000000")
    OPTIMAL_GAS=$(echo "scale=0; $CURRENT_GAS * 1.5 / 1" | bc 2>/dev/null || echo "$CURRENT_GAS")
fi

log_info "Using gas price: $(echo "scale=2; $OPTIMAL_GAS / 1000000000" | bc) gwei"

# Deploy using forge create (direct deployment, avoids compilation issues)
cd "$DEPLOY_DIR"

if [ "${USE_MOCK:-false}" = true ]; then
    CONTRACT_PATH="contracts/tokens/MockLinkToken.sol:MockLinkToken"
    log_info "Deploying MockLinkToken using forge create..."
    
    # Deploy directly - forge create should handle dependencies
    DEPLOY_OUTPUT=$(forge create \
        "$CONTRACT_PATH" \
        --rpc-url "$RPC_URL" \
        --private-key "$PRIVATE_KEY" \
        --gas-price "$OPTIMAL_GAS" \
        2>&1 || echo "FAILED")
else
    if [ "$DEPLOY_DIR" = "$TEMP_DIR" ]; then
        CONTRACT_PATH="src/LinkToken.sol:LinkToken"
    else
        CONTRACT_PATH="contracts/LinkToken.sol:LinkToken"
    fi
    log_info "Deploying LinkToken using forge create..."
    
    DEPLOY_OUTPUT=$(forge create \
        "$CONTRACT_PATH" \
        --rpc-url "$RPC_URL" \
        --private-key "$PRIVATE_KEY" \
        --gas-price "$OPTIMAL_GAS" \
        2>&1 || echo "FAILED")
fi

# Extract deployed address from output (handle both forge script and forge create formats)
DEPLOYED_ADDRESS=""
TX_HASH=""

if echo "$DEPLOY_OUTPUT" | grep -qE "Deployed to:"; then
    DEPLOYED_ADDRESS=$(echo "$DEPLOY_OUTPUT" | grep -oE "Deployed to: 0x[0-9a-fA-F]{40}" | awk '{print $3}')
    TX_HASH=$(echo "$DEPLOY_OUTPUT" | grep -oE "Transaction hash: 0x[0-9a-fA-F]{64}" | awk '{print $3}')
elif echo "$DEPLOY_OUTPUT" | grep -qE "Mock LINK Token deployed at:"; then
    DEPLOYED_ADDRESS=$(echo "$DEPLOY_OUTPUT" | grep -oE "Mock LINK Token deployed at: 0x[0-9a-fA-F]{40}" | awk '{print $5}')
    TX_HASH=$(echo "$DEPLOY_OUTPUT" | grep -oE "0x[0-9a-fA-F]{64}" | head -1)
fi

if [ -n "$DEPLOYED_ADDRESS" ] && [ "$DEPLOYED_ADDRESS" != "0x0000000000000000000000000000000000000000" ]; then
    
    log_success "✓ LINK token deployed successfully!"
    log_info ""
    log_info "Contract Address: $DEPLOYED_ADDRESS"
    log_info "Transaction Hash: $TX_HASH"
    log_info ""
    
    # Verify deployment
    log_info "Verifying deployment..."
    sleep 5
    
    NAME=$(cast call "$DEPLOYED_ADDRESS" "name()" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
    SYMBOL=$(cast call "$DEPLOYED_ADDRESS" "symbol()" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
    TOTAL_SUPPLY=$(cast call "$DEPLOYED_ADDRESS" "totalSupply()" --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
    DEPLOYER_BALANCE=$(cast call "$DEPLOYED_ADDRESS" "balanceOf(address)" "$DEPLOYER" --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
    
    if [ -n "$NAME" ] && [ -n "$SYMBOL" ]; then
        log_success "✓ Deployment verified!"
        log_info "  Name: $NAME"
        log_info "  Symbol: $SYMBOL"
        log_info "  Total Supply: $(cast --from-wei "$TOTAL_SUPPLY" ether) LINK"
        log_info "  Deployer Balance: $(cast --from-wei "$DEPLOYER_BALANCE" ether) LINK"
        log_info ""
        
        if [ "$DEPLOYED_ADDRESS" != "$EXPECTED_LINK_ADDRESS" ]; then
            log_warn "⚠️  Deployed address differs from expected address"
            log_info "  Expected: $EXPECTED_LINK_ADDRESS"
            log_info "  Deployed: $DEPLOYED_ADDRESS"
            log_info ""
            log_info "Update your .env file:"
            log_info "  LINK_TOKEN=$DEPLOYED_ADDRESS"
            log_info "  CCIP_CHAIN138_LINK_TOKEN=$DEPLOYED_ADDRESS"
        else
            log_success "✓ Deployed to expected address!"
        fi
        
        log_info ""
        log_info "Next steps:"
        log_info "1. Update config/address-inventory.json with LINK token address"
        log_info "2. Fund bridge contracts: ./scripts/fund-bridge-contracts.sh 10"
        log_info "3. Verify contract on explorer: https://explorer.d-bis.org/address/$DEPLOYED_ADDRESS"
        
        exit 0
    else
        log_error "Deployment verification failed"
        log_error "Contract may not be a valid ERC20 token"
        exit 1
    fi
else
    log_error "Deployment failed"
    log_error "$DEPLOY_OUTPUT"
    exit 1
fi
