#!/usr/bin/env bash
# Force Deploy LINK Token - All Methods
# Tries multiple approaches to force forge to broadcast
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

source "$PROJECT_ROOT/.env" 2>/dev/null || source "$PROJECT_ROOT/../.env" 2>/dev/null || true

RPC_URL="${RPC_URL_138:-http://192.168.11.250:8545}"
FORCE_GAS="${1:-5000000000}"  # Default 5 gwei (increased for better confirmation)

# Export variables to ensure they're available in subshells
export RPC_URL
export PRIVATE_KEY

echo "╔══════════════════════════════════════════════════════════════╗"
echo "║     FORCE DEPLOY LINK TOKEN - ALL METHODS                    ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo "RPC: $RPC_URL"
echo "Forced Gas: $(echo "scale=2; $FORCE_GAS / 1000000000" | bc) gwei"
echo ""

TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT

cd "$TEMP_DIR"
forge init --no-git --force . > /dev/null 2>&1

cat > src/MockLinkToken.sol << 'EOF'
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract MockLinkToken {
    string public name = "Chainlink Token";
    string public symbol = "LINK";
    uint8 public decimals = 18;
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;
    uint256 public totalSupply;
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    function mint(address to, uint256 amount) external {
        balanceOf[to] += amount;
        totalSupply += amount;
        emit Transfer(address(0), to, amount);
    }
    function transfer(address to, uint256 amount) external returns (bool) {
        require(balanceOf[msg.sender] >= amount, "insufficient balance");
        balanceOf[msg.sender] -= amount;
        balanceOf[to] += amount;
        emit Transfer(msg.sender, to, amount);
        return true;
    }
    function transferFrom(address from, address to, uint256 amount) external returns (bool) {
        require(balanceOf[from] >= amount, "insufficient balance");
        require(allowance[from][msg.sender] >= amount, "insufficient allowance");
        balanceOf[from] -= amount;
        balanceOf[to] += amount;
        allowance[from][msg.sender] -= amount;
        emit Transfer(from, to, amount);
        return true;
    }
    function approve(address spender, uint256 amount) external returns (bool) {
        allowance[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }
}
EOF

cat > script/DeployLink.s.sol << 'EOF'
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {Script, console} from "forge-std/Script.sol";
import {MockLinkToken} from "../src/MockLinkToken.sol";
contract DeployLink is Script {
    function run() external {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);
        MockLinkToken link = new MockLinkToken();
        console.log("LINK_TOKEN_ADDRESS", address(link));
        link.mint(vm.addr(deployerPrivateKey), 1_000_000e18);
        vm.stopBroadcast();
    }
}
EOF

cat > foundry.toml << EOF
[profile.default]
gas_price = $FORCE_GAS
legacy = true

[rpc_endpoints]
chain138 = "$RPC_URL"
EOF

export PRIVATE_KEY

echo "=== Method 1: forge script with --broadcast --skip-simulation ==="
DEPLOY_OUTPUT=$(forge script script/DeployLink.s.sol:DeployLink \
    --rpc-url "$RPC_URL" \
    --private-key "$PRIVATE_KEY" \
    --broadcast \
    --skip-simulation \
    --gas-price "$FORCE_GAS" \
    --legacy \
    -vv 2>&1) || true

LINK_ADDRESS=$(echo "$DEPLOY_OUTPUT" | grep -oE "LINK_TOKEN_ADDRESS[[:space:]]+0x[0-9a-fA-F]{40}" | awk '{print $2}' || echo "")

# Verify broadcast actually happened
if echo "$DEPLOY_OUTPUT" | grep -qi "dry run\|simulation only\|not broadcasting"; then
    echo "⚠️  WARNING: Script may have run in dry-run mode despite --broadcast flag"
    echo "Output contains dry-run indicators"
    LINK_ADDRESS=""  # Clear address if dry-run detected
fi

# Verify deployment actually happened on-chain (not just simulation)
if [ -n "$LINK_ADDRESS" ] && [ ${#LINK_ADDRESS} -eq 42 ]; then
    echo "Address extracted: $LINK_ADDRESS"
    echo "Verifying on-chain deployment (waiting 15 seconds)..."
    sleep 15  # Wait for transaction to propagate
    CODE=$(cast code "$LINK_ADDRESS" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
    if [ -n "$CODE" ] && [ "$CODE" != "0x" ] && [ ${#CODE} -gt 100 ]; then
        echo "✓✓✓ SUCCESS! LINK deployed and CONFIRMED: $LINK_ADDRESS"
        echo "$LINK_ADDRESS" > /tmp/link_address.txt
        exit 0
    else
        echo "⚠️  Address extracted but contract not yet on-chain"
        echo "This may be from simulation. Trying Method 2..."
        LINK_ADDRESS=""  # Clear to force Method 2
    fi
fi

echo "Method 1 failed, trying Method 2..."
echo ""

echo "=== Method 2: forge create with explicit gas and verify ==="
# Ensure RPC_URL is set and not empty
if [ -z "$RPC_URL" ]; then
    echo "ERROR: RPC_URL is not set!"
    RPC_URL="http://192.168.11.250:8545"
    echo "Using default: $RPC_URL"
    export RPC_URL
fi

# Ensure PRIVATE_KEY is set
if [ -z "$PRIVATE_KEY" ]; then
    echo "ERROR: PRIVATE_KEY is not set!"
    echo "Cannot deploy without private key"
    exit 1
fi

echo "Deploying with forge create (this may take a moment)..."
DEPLOY_OUTPUT=$(forge create src/MockLinkToken.sol:MockLinkToken \
    --rpc-url "$RPC_URL" \
    --private-key "$PRIVATE_KEY" \
    --gas-price "$FORCE_GAS" \
    --gas-limit 10000000 \
    --legacy \
    --broadcast \
    2>&1) || true

echo "Deployment output:"
echo "$DEPLOY_OUTPUT" | head -20

LINK_ADDRESS=$(echo "$DEPLOY_OUTPUT" | grep -oE "Deployed to: 0x[0-9a-fA-F]{40}" | awk '{print $3}' || echo "")

# Also check for errors
if echo "$DEPLOY_OUTPUT" | grep -qi "error\|fail\|revert"; then
    echo "⚠️  Deployment errors detected in output above"
fi

if [ -n "$LINK_ADDRESS" ] && [ ${#LINK_ADDRESS} -eq 42 ]; then
    echo "✓✓✓ SUCCESS! LINK deployed: $LINK_ADDRESS"
    echo "$LINK_ADDRESS" > /tmp/link_address.txt
    exit 0
fi

echo "Method 2 failed, trying Method 3..."
echo ""

echo "=== Method 3: Get bytecode and deploy via cast send ==="
forge build > /dev/null 2>&1
BYTECODE=$(cat out/MockLinkToken.sol/MockLinkToken.json | jq -r '.bytecode.object' 2>/dev/null || echo "")

if [ -n "$BYTECODE" ] && [ "$BYTECODE" != "null" ] && [ ${#BYTECODE} -gt 100 ]; then
    ACCOUNT=$(cast wallet address "$PRIVATE_KEY")
    NONCE=$(cast nonce "$ACCOUNT" --rpc-url "$RPC_URL")
    
    echo "Deploying via cast send..."
    TX_OUTPUT=$(timeout 60 cast send --create "$BYTECODE" \
        --rpc-url "$RPC_URL" \
        --private-key "$PRIVATE_KEY" \
        --gas-price "$FORCE_GAS" \
        --nonce "$NONCE" \
        --legacy \
        2>&1) || true
    
    LINK_ADDRESS=$(echo "$TX_OUTPUT" | grep -oE "contractAddress[[:space:]]+0x[0-9a-fA-F]{40}" | awk '{print $2}' || echo "")
    
    if [ -z "$LINK_ADDRESS" ]; then
        LINK_ADDRESS=$(echo "$TX_OUTPUT" | grep -oE "0x[0-9a-fA-F]{40}" | head -1 || echo "")
    fi
    
    if [ -n "$LINK_ADDRESS" ] && [ ${#LINK_ADDRESS} -eq 42 ]; then
        echo "✓✓✓ SUCCESS! LINK deployed: $LINK_ADDRESS"
        echo "$LINK_ADDRESS" > /tmp/link_address.txt
        exit 0
    fi
fi

echo ""
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║     ALL METHODS FAILED                                       ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo "Possible issues:"
echo "1. Network RPC not responding"
echo "2. Stuck transaction at nonce 37 blocking new transactions"
echo "3. Network requires different gas configuration"
echo "4. Private key or account issues"
echo ""
echo "Recommendation: Use Remix IDE to deploy"
echo "  https://remix.ethereum.org"
echo ""
exit 1

