import base64
import json
import tempfile
import unittest
from pathlib import Path

from manage_routes_web import basic_auth_ok, load_routes, save_routes, validate_routes


class ManageRoutesWebTests(unittest.TestCase):
    def test_validate_routes_normalizes_domains_and_mailbox(self):
        routes = validate_routes([
            {"domains": [" Example.COM ", "example.com"], "mailbox": " Diensten.Test "}
        ])
        self.assertEqual(routes, [{"domains": ["example.com"], "mailbox": "Diensten.Test"}])

    def test_validate_routes_rejects_duplicate_domain_across_routes(self):
        with self.assertRaisesRegex(ValueError, "already used"):
            validate_routes([
                {"domains": ["example.com"], "mailbox": "Diensten.Een"},
                {"domains": ["EXAMPLE.com"], "mailbox": "Diensten.Twee"},
            ])

    def test_save_routes_writes_backup_and_normalized_json(self):
        with tempfile.TemporaryDirectory() as tmp:
            path = Path(tmp) / "domain_routes.json"
            path.write_text(
                json.dumps([{"domains": ["old.example"], "mailbox": "Diensten.Oud"}]) + "\n",
                encoding="utf-8",
            )

            saved = save_routes(
                [{"domains": [" New.EXAMPLE "], "mailbox": " Diensten.Nieuw "}],
                path,
            )

            self.assertEqual(saved, [{"domains": ["new.example"], "mailbox": "Diensten.Nieuw"}])
            self.assertEqual(load_routes(path), saved)
            backup = path.with_suffix(".json.bak")
            self.assertTrue(backup.exists())
            self.assertIn("old.example", backup.read_text(encoding="utf-8"))

    def test_basic_auth_ok_accepts_exact_credentials(self):
        token = base64.b64encode(b"mailcat:secret").decode("ascii")
        self.assertTrue(basic_auth_ok(f"Basic {token}", "mailcat", "secret"))
        self.assertFalse(basic_auth_ok(f"Basic {token}", "mailcat", "wrong"))
        self.assertFalse(basic_auth_ok(None, "mailcat", "secret"))


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