import os
from unittest.mock import patch, MagicMock

import pytest

from agentcost import AgentCost
from agentcost.tracker import _active_run


class TestAgentCostInit:
    def test_accepts_explicit_api_key(self):
        ac = AgentCost(api_key="ac_test123")
        assert ac._api_key == "ac_test123"
        ac.shutdown()

    def test_reads_api_key_from_env(self):
        with patch.dict(os.environ, {"AGENTCOST_API_KEY": "ac_from_env"}):
            ac = AgentCost()
            assert ac._api_key == "ac_from_env"
            ac.shutdown()

    def test_explicit_key_overrides_env(self):
        with patch.dict(os.environ, {"AGENTCOST_API_KEY": "ac_env"}):
            ac = AgentCost(api_key="ac_explicit")
            assert ac._api_key == "ac_explicit"
            ac.shutdown()

    def test_raises_without_key_or_debug(self):
        with patch.dict(os.environ, {}, clear=True), \
             patch("agentcost.credentials.load", return_value=None):
            env = os.environ.copy()
            env.pop("AGENTCOST_API_KEY", None)
            with patch.dict(os.environ, env, clear=True):
                with pytest.raises(ValueError, match="No API key found"):
                    AgentCost()

    def test_debug_mode_works_without_key(self):
        ac = AgentCost(debug=True)
        assert ac._debug is True
        ac.shutdown()


class TestTrackTool:
    def test_decorator_tracks_cost(self):
        ac = AgentCost(debug=True)

        @ac.track_tool(name="my_tool", cost_per_call=0.05)
        def my_func():
            return "result"

        result = my_func()
        assert result == "result"
        ac.shutdown()

    def test_decorator_links_to_active_run(self):
        ac = AgentCost(debug=True)

        @ac.track_tool(name="my_tool", cost_per_call=0.05)
        def my_func():
            return "result"

        with ac.track_run("test-agent", task="test") as run:
            my_func()
            # The tool event should be linked to the run
            assert len(run.events) == 1
            assert run.events[0].component_name == "my_tool"
            assert run.events[0].run_id == run._run_id

        ac.shutdown()

    def test_decorator_standalone_without_run(self):
        ac = AgentCost(debug=True)

        @ac.track_tool(name="standalone", cost_per_call=0.01)
        def my_func():
            return 42

        result = my_func()
        assert result == 42
        ac.shutdown()

    def test_decorator_uses_function_name_when_no_name(self):
        ac = AgentCost(debug=True)

        @ac.track_tool(cost_per_call=0.01)
        def search_salesforce():
            return []

        # The decorator should use "search_salesforce" as the tool name
        assert search_salesforce.__name__ == "search_salesforce"
        ac.shutdown()
