from __future__ import annotations

import ast
import unittest
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
FEATURES = ROOT / "backend" / "features"


class FeatureBoundaryTests(unittest.TestCase):
    def test_feature_services_do_not_import_http_or_provider_adapters(self) -> None:
        forbidden = {
            "server",
            "tushare_client",
            "ifind_client",
            "chart_data_provider",
            "realtime_aggregator",
        }
        violations = []
        for path in FEATURES.rglob("*.py"):
            tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
            for node in ast.walk(tree):
                names = []
                if isinstance(node, ast.Import):
                    names = [alias.name for alias in node.names]
                elif isinstance(node, ast.ImportFrom) and node.module:
                    names = [node.module]
                for name in names:
                    if name.split(".")[0] in forbidden:
                        violations.append(f"{path.relative_to(ROOT)} -> {name}")
        self.assertEqual(violations, [])

    def test_legacy_service_modules_are_compatibility_exports_only(self) -> None:
        for filename in ("alert_service.py", "trade_journal.py", "strategy_tracking.py"):
            tree = ast.parse((ROOT / filename).read_text(encoding="utf-8"))
            definitions = [
                node for node in tree.body
                if isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef))
            ]
            self.assertEqual(definitions, [], filename)

    def test_each_migrated_feature_owns_one_application_service(self) -> None:
        expected = {
            "alerts/service.py": "AlertService",
            "review/trade_journal.py": "TradeJournalService",
            "screener/tracking.py": "StrategyTrackingService",
        }
        for relative, class_name in expected.items():
            tree = ast.parse((FEATURES / relative).read_text(encoding="utf-8"))
            self.assertIn(class_name, {node.name for node in tree.body if isinstance(node, ast.ClassDef)})


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