from __future__ import annotations

import tempfile
import unittest
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import MagicMock

from phs.core.database import Database
from phs.modules.account_usage import AccountUsageModule


class FakeConfig:
    def getint(self, section, option, fallback=0):
        values = {
            ("account_usage", "interval"): 300,
            ("account_usage", "full_percent"): 100,
            ("account_usage", "critical_percent"): 90,
            ("account_usage", "warning_percent"): 80,
            ("account_usage", "watch_percent"): 70,
        }
        return values.get((section, option), fallback)


class AccountUsageModuleTests(unittest.TestCase):
    def setUp(self) -> None:
        self.temp = tempfile.TemporaryDirectory()
        self.db = Database(Path(self.temp.name) / "db.sqlite3")
        logger = MagicMock()
        logger.getChild.return_value = MagicMock()
        self.module = AccountUsageModule(SimpleNamespace(
            config=FakeConfig(), database=self.db, logger=logger,
            notifier=MagicMock(), tailer=MagicMock(),
        ))

    def tearDown(self) -> None:
        self.db.close()
        self.temp.cleanup()

    def test_collects_plan_suspension_and_orders_quota_state(self) -> None:
        def fake_api(function, **_params):
            if function == "listaccts":
                return {
                    "metadata": {"result": 1},
                    "data": {"acct": [
                        {"user": "full", "domain": "full.test", "plan": "Plan 1G", "diskused": "1.1G", "disklimit": "1G", "suspended": 0},
                        {"user": "warn", "domain": "warn.test", "plan": "Plan 10G", "diskused": "8.5G", "disklimit": "10G", "suspended": 1, "suspendreason": "Falta de pago"},
                        {"user": "free", "domain": "free.test", "plan": "Ilimitado", "diskused": "2G", "disklimit": "unlimited", "suspended": 0},
                    ]},
                }
            return {"metadata": {"result": 1}, "data": {"accounts": []}}

        self.module._whmapi = fake_api  # type: ignore[method-assign]
        detail = self.module.run()
        self.assertIn("3 cuentas", detail)
        rows = self.db.query(
            "SELECT username,quota_state,suspended,plan FROM account_usage ORDER BY CASE quota_state WHEN 'full' THEN 0 WHEN 'warning' THEN 1 ELSE 2 END"
        )
        self.assertEqual(rows[0]["username"], "full")
        self.assertEqual(rows[0]["quota_state"], "full")
        warn = next(row for row in rows if row["username"] == "warn")
        self.assertEqual(warn["quota_state"], "warning")
        self.assertEqual(warn["suspended"], 1)
        free = next(row for row in rows if row["username"] == "free")
        self.assertEqual(free["quota_state"], "unlimited")


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