from decimal import Decimal

import pytest

from src.execution.hyperliquid_live_executor import HyperliquidLiveExecutor
from src.execution.order_intent import OrderIntent


def _intent():
    return OrderIntent(
        strategy_id="candidate_v76_hl_confirmed_squeeze_hybrid",
        symbol="BTC/USDC:USDC",
        coin="BTC",
        side="buy",
        reduce_only=False,
        order_type="market",
        tif="Ioc",
        size=Decimal("0.01"),
        price=None,
        trigger_price=None,
        stop_loss=Decimal("99000"),
        take_profit=None,
        client_order_id="v76-BTC-1",
        reason="confirmed_squeeze_breakout",
        risk_usd=Decimal("1.25"),
        estimated_notional_usd=Decimal("100"),
    )


class FakeExchange:
    def __init__(self):
        self.calls = []

    def market_open(self, *args, **kwargs):
        self.calls.append((args, kwargs))
        return {"status": "ok"}


def test_live_executor_blocks_without_env_gates(monkeypatch):
    monkeypatch.delenv("CTB_LIVE_TRADING_ALLOWED", raising=False)
    monkeypatch.delenv("CTB_LIVE_CONFIRMATION", raising=False)
    fake = FakeExchange()
    executor = HyperliquidLiveExecutor(exchange=fake, expected_confirmation="LIVE PREVIEW BTC")

    with pytest.raises(PermissionError, match="CTB_LIVE_TRADING_ALLOWED"):
        executor.execute(_intent())

    assert fake.calls == []


def test_live_executor_dry_run_returns_plan_without_exchange_call(monkeypatch):
    monkeypatch.delenv("CTB_LIVE_TRADING_ALLOWED", raising=False)
    fake = FakeExchange()
    executor = HyperliquidLiveExecutor(exchange=fake, expected_confirmation="LIVE PREVIEW BTC", dry_run=True)

    result = executor.execute(_intent())

    assert result.status == "dry_run"
    assert result.side_effects == ()
    assert fake.calls == []
