"""tools_registry 모듈 테스트 — LLM 불필요."""

import polars as pl
import pytest

from dartlab.engines.llmAnalyzer.tools_registry import (
	clear_registry,
	execute_tool,
	get_tool_schemas,
	register_defaults,
	register_tool,
)


# ══════════════════════════════════════
# Mock Company
# ══════════════════════════════════════

class MockCompany:
	"""테스트용 가짜 Company."""

	def __init__(self):
		self.corpName = "테스트기업"
		self.stockCode = "000000"
		self.BS = pl.DataFrame({
			"계정명": ["자산총계", "부채총계", "자본총계", "유동자산", "유동부채"],
			"2023": [15000, 5000, 10000, 8000, 4000],
			"2022": [13000, 4000, 9000, 7000, 3500],
		})
		self.IS = pl.DataFrame({
			"계정명": ["매출액", "영업이익", "당기순이익"],
			"2023": [20000, 3000, 2000],
			"2022": [18000, 2500, 1800],
		})
		self.CF = pl.DataFrame({
			"계정명": ["영업활동으로인한현금흐름"],
			"2023": [5000],
			"2022": [3000],
		})
		self.dividend = pl.DataFrame({
			"year": [2022, 2023],
			"dps": [1200, 1500],
		})
		self.companyOverview = {
			"ceo": "홍길동",
			"mainBusiness": "소프트웨어",
			"indutyName": "IT서비스",
		}


# ══════════════════════════════════════
# register_tool / execute_tool
# ══════════════════════════════════════

class TestRegisterTool:
	def setup_method(self):
		clear_registry()

	def test_register_and_execute(self):
		register_tool(
			"hello",
			lambda name="World": f"Hello, {name}!",
			"인사 도구",
			{
				"type": "object",
				"properties": {"name": {"type": "string"}},
			},
		)
		result = execute_tool("hello", {"name": "DartLab"})
		assert result == "Hello, DartLab!"

	def test_execute_unknown(self):
		result = execute_tool("nonexistent", {})
		assert "찾을 수 없습니다" in result

	def test_get_schemas(self):
		register_tool(
			"test_tool",
			lambda: "ok",
			"테스트 도구",
			{"type": "object", "properties": {}},
		)
		schemas = get_tool_schemas()
		assert len(schemas) == 1
		assert schemas[0]["type"] == "function"
		assert schemas[0]["function"]["name"] == "test_tool"

	def test_clear(self):
		register_tool("x", lambda: "y", "d", {"type": "object", "properties": {}})
		assert len(get_tool_schemas()) == 1
		clear_registry()
		assert len(get_tool_schemas()) == 0

	def test_error_handling(self):
		"""실행 중 에러가 발생하면 에러 메시지 반환."""
		def bad_func():
			raise ValueError("test error")

		register_tool("bad", bad_func, "d", {"type": "object", "properties": {}})
		result = execute_tool("bad", {})
		assert "오류" in result
		assert "test error" in result


# ══════════════════════════════════════
# register_defaults
# ══════════════════════════════════════

class TestRegisterDefaults:
	def setup_method(self):
		clear_registry()

	def test_registers_tools(self):
		company = MockCompany()
		register_defaults(company)
		schemas = get_tool_schemas()
		assert len(schemas) >= 6
		names = [s["function"]["name"] for s in schemas]
		assert "get_data" in names
		assert "compute_ratios" in names
		assert "detect_anomalies" in names
		assert "compute_growth" in names
		assert "yoy_analysis" in names
		assert "get_summary" in names
		assert "get_company_info" in names

	def test_get_data(self):
		company = MockCompany()
		register_defaults(company)
		result = execute_tool("get_data", {"module_name": "BS"})
		assert "자산총계" in result or "부채총계" in result

	def test_get_data_missing(self):
		company = MockCompany()
		register_defaults(company)
		result = execute_tool("get_data", {"module_name": "nonexistent"})
		assert "없습니다" in result

	def test_compute_ratios(self):
		company = MockCompany()
		register_defaults(company)
		result = execute_tool("compute_ratios", {})
		assert "부채비율" in result or "ROE" in result or "|" in result

	def test_detect_anomalies_no_anomalies(self):
		company = MockCompany()
		register_defaults(company)
		result = execute_tool("detect_anomalies", {"module_name": "CF"})
		# CF에 큰 변동이 있을 수 있으므로 결과 타입만 확인
		assert isinstance(result, str)

	def test_get_company_info(self):
		company = MockCompany()
		register_defaults(company)
		result = execute_tool("get_company_info", {})
		assert "테스트기업" in result
		assert "000000" in result

	def test_yoy_analysis(self):
		company = MockCompany()
		register_defaults(company)
		result = execute_tool("yoy_analysis", {"module_name": "IS"})
		assert isinstance(result, str)

	def test_get_summary(self):
		company = MockCompany()
		register_defaults(company)
		result = execute_tool("get_summary", {"module_name": "dividend"})
		assert isinstance(result, str)
