"""Tests for the PortfolioModule."""

from __future__ import annotations

from unittest.mock import AsyncMock, patch

import pytest
from eth_abi import encode

from openhedge.models.portfolio import Portfolio
from openhedge.models.trade import Position
from tests.conftest import FAKE_VAULT, make_rpc_response


def _encode_rpc(types, values):
    return "0x" + encode(types, values).hex()


class TestPortfolioGet:
    async def test_get_portfolio(self, agent):
        responses = [
            make_rpc_response(_encode_rpc(["uint256"], [10_000_000])),  # totalAssets
            make_rpc_response(_encode_rpc(["uint256"], [1_050_000])),   # sharePrice
            make_rpc_response(_encode_rpc(["uint256"], [9_523_809])),   # totalSupply
            # getOpenTradeIndices — gains adapter is 0x000...0 so this won't be called
        ]

        call_count = 0
        async def mock_post(*args, **kwargs):
            nonlocal call_count
            resp = responses[min(call_count, len(responses) - 1)]
            call_count += 1
            return resp

        with patch.object(agent._http, "post", side_effect=mock_post):
            portfolio = await agent.portfolio.get(FAKE_VAULT)

        assert isinstance(portfolio, Portfolio)
        assert portfolio.total_assets == 10_000_000
        assert portfolio.share_price == 1_050_000
        assert portfolio.open_positions_count == 0


class TestPortfolioPositions:
    async def test_positions_empty_gains(self, agent):
        """When the gains adapter is 0x000..., return empty list."""
        positions = await agent.portfolio.positions(FAKE_VAULT)
        assert positions == []
