"""对冲计划与单独期权互斥门控."""
from __future__ import annotations

import os
import sqlite3
import unittest
from unittest import mock

from lib.hedge_plan.hedge_options_exclusive_lib import (
    block_hedge_plan_start_msg,
    block_standalone_option_open_msg,
    has_standalone_option_position,
    mutual_exclusive_enabled,
)
from lib.hedge_plan.hedge_plan_calc_lib import gate_status
from lib.hedge_plan.hedge_plan_db import init_hedge_plan_tables


class HedgeOptionsExclusiveTests(unittest.TestCase):
    def test_mutual_default_true(self):
        with mock.patch.dict(os.environ, {}, clear=False):
            os.environ.pop("HEDGE_PLAN_OPTIONS_MUTUAL_EXCLUSIVE", None)
            self.assertTrue(mutual_exclusive_enabled())

    def test_mutual_can_disable(self):
        with mock.patch.dict(os.environ, {"HEDGE_PLAN_OPTIONS_MUTUAL_EXCLUSIVE": "false"}):
            self.assertFalse(mutual_exclusive_enabled())

    def test_block_open_when_active_plan(self):
        conn = sqlite3.connect(":memory:")
        conn.row_factory = sqlite3.Row
        init_hedge_plan_tables(conn)
        conn.execute(
            "INSERT INTO hedge_plans (plan_type, underlying, status) "
            "VALUES ('options_options', 'ETH', 'active')"
        )
        conn.commit()
        with mock.patch.dict(os.environ, {"HEDGE_PLAN_OPTIONS_MUTUAL_EXCLUSIVE": "true"}):
            msg = block_standalone_option_open_msg(conn)
        self.assertIsNotNone(msg)
        self.assertIn("对冲计划", msg or "")
        with mock.patch.dict(os.environ, {"HEDGE_PLAN_OPTIONS_MUTUAL_EXCLUSIVE": "false"}):
            self.assertIsNone(block_standalone_option_open_msg(conn))
        conn.close()

    def test_standalone_position_detection(self):
        conn = sqlite3.connect(":memory:")
        conn.row_factory = sqlite3.Row
        init_hedge_plan_tables(conn)
        raw = [{"instId": "ETH-USD_UM-260719-1890-C", "pos": "1"}]
        with mock.patch(
            "lib.instance.instance_dashboard_lib._resolve_options_source",
            return_value=("option", "纯期权", None),
        ):
            self.assertTrue(has_standalone_option_position(conn, raw))
        with mock.patch(
            "lib.instance.instance_dashboard_lib._resolve_options_source",
            return_value=("options_options", "期期对冲", 2),
        ):
            self.assertFalse(has_standalone_option_position(conn, raw))
        conn.close()

    def test_block_hedge_start_msg(self):
        conn = sqlite3.connect(":memory:")
        conn.row_factory = sqlite3.Row
        init_hedge_plan_tables(conn)
        raw = [{"instId": "ETH-USD_UM-260719-1890-C", "pos": "2"}]
        with mock.patch.dict(os.environ, {"HEDGE_PLAN_OPTIONS_MUTUAL_EXCLUSIVE": "true"}):
            with mock.patch(
                "lib.instance.instance_dashboard_lib._resolve_options_source",
                return_value=("option", "纯期权", None),
            ):
                msg = block_hedge_plan_start_msg(conn, raw_positions=raw)
        self.assertIsNotNone(msg)
        self.assertIn("单独期权", msg or "")
        conn.close()

    def test_gate_status_blocks_start(self):
        g = gate_status(
            hedge_enabled=True,
            sizing_mode="full_margin",
            plan_type="options_options",
            options_enabled=True,
            live_order=True,
            mutual_exclusive=True,
            has_standalone_option=True,
        )
        self.assertFalse(g["can_start"])
        self.assertTrue(any("单独期权" in r for r in g["reasons"]))
        g2 = gate_status(
            hedge_enabled=True,
            sizing_mode="full_margin",
            plan_type="options_options",
            options_enabled=True,
            live_order=True,
            mutual_exclusive=False,
            has_standalone_option=True,
        )
        self.assertTrue(g2["can_start"])


if __name__ == "__main__":
    unittest.main()
