"""
T-BOOT: Bootstrap idempotency and demo state verification.

Tests that the demo config can be loaded twice without errors
and that all expected objects exist afterwards.
"""

import pytest
from modules.datamodels.datamodelUam import Mandate, UserInDB
from modules.datamodels.datamodelFeatures import FeatureInstance
from modules.datamodels.datamodelMembership import UserMandate
from tests.demo.conftest import _getFeatureInstances


class TestDemoBootstrap:

    def test_loadIsIdempotent(self, db, demoConfig):
        """Loading the demo config twice must not raise errors."""
        summary1 = demoConfig.load(db)
        assert "errors" not in summary1 or len(summary1.get("errors", [])) == 0, f"First load errors: {summary1['errors']}"

        summary2 = demoConfig.load(db)
        assert "errors" not in summary2 or len(summary2.get("errors", [])) == 0, f"Second load errors: {summary2['errors']}"

    def test_mandateHappylifeExists(self, db):
        records = db.getRecordset(Mandate, recordFilter={"name": "happylife"})
        assert len(records) == 1
        assert records[0].get("label") == "HappyLife AG"
        assert records[0].get("enabled") is True

    def test_mandateAlpinaExists(self, db):
        records = db.getRecordset(Mandate, recordFilter={"name": "alpina-treuhand"})
        assert len(records) == 1
        assert records[0].get("label") == "Alpina Treuhand AG"

    def test_userPatrickExists(self, db):
        records = db.getRecordset(UserInDB, recordFilter={"username": "patrick.helvetia"})
        assert len(records) == 1
        user = records[0]
        assert user.get("email") == "p.motsch@poweron.swiss"
        assert user.get("isSysAdmin") is True
        assert user.get("language") == "en"

    def test_userMembershipBothMandates(self, db, demoUser, mandateHappylife, mandateAlpina):
        userId = demoUser.get("id")
        for mandate in [mandateHappylife, mandateAlpina]:
            mid = mandate.get("id")
            memberships = db.getRecordset(UserMandate, recordFilter={"userId": userId, "mandateId": mid})
            assert len(memberships) >= 1, f"User not member of mandate {mandate.get('label')}"

    @pytest.mark.parametrize("featureCode", ["workspace", "trustee", "graphicalEditor", "chatbot", "neutralization"])
    def test_happylifeFeaturesExist(self, db, mandateHappylife, featureCode):
        mid = mandateHappylife.get("id")
        instances = _getFeatureInstances(db, mid, featureCode)
        assert len(instances) >= 1, f"Feature '{featureCode}' missing in HappyLife AG"

    @pytest.mark.parametrize("featureCode", ["workspace", "trustee", "graphicalEditor", "neutralization"])
    def test_alpinaFeaturesExist(self, db, mandateAlpina, featureCode):
        mid = mandateAlpina.get("id")
        instances = _getFeatureInstances(db, mid, featureCode)
        assert len(instances) >= 1, f"Feature '{featureCode}' missing in Alpina Treuhand AG"

    def test_alpinaNoChatbot(self, db, mandateAlpina):
        """Alpina should NOT have a chatbot instance."""
        mid = mandateAlpina.get("id")
        instances = _getFeatureInstances(db, mid, "chatbot")
        assert len(instances) == 0, "Alpina Treuhand should not have chatbot"


class TestDemoBootstrapRma:

    def test_trusteeRmaConfigHappylife(self, db, mandateHappylife):
        from modules.features.trustee.datamodelFeatureTrustee import TrusteeAccountingConfig
        mid = mandateHappylife.get("id")
        instances = _getFeatureInstances(db, mid, "trustee")
        assert instances, "No trustee instance in HappyLife"
        iid = instances[0].get("id")
        configs = db.getRecordset(TrusteeAccountingConfig, recordFilter={"featureInstanceId": iid})
        assert len(configs) >= 1, "No RMA config for HappyLife trustee"
        assert configs[0].get("connectorType") == "rma"
        assert configs[0].get("isActive") is True

    def test_trusteeRmaConfigAlpina(self, db, mandateAlpina):
        from modules.features.trustee.datamodelFeatureTrustee import TrusteeAccountingConfig
        mid = mandateAlpina.get("id")
        instances = _getFeatureInstances(db, mid, "trustee")
        assert instances, "No trustee instance in Alpina"
        iid = instances[0].get("id")
        configs = db.getRecordset(TrusteeAccountingConfig, recordFilter={"featureInstanceId": iid})
        assert len(configs) >= 1, "No RMA config for Alpina trustee"
        assert configs[0].get("connectorType") == "rma"


class TestDemoBootstrapNeutralization:

    def test_neutralizationConfigHappylife(self, db, mandateHappylife):
        from modules.features.neutralization.datamodelFeatureNeutralizer import DataNeutraliserConfig
        mid = mandateHappylife.get("id")
        instances = _getFeatureInstances(db, mid, "neutralization")
        assert instances
        iid = instances[0].get("id")
        configs = db.getRecordset(DataNeutraliserConfig, recordFilter={"featureInstanceId": iid})
        assert len(configs) >= 1, "No neutralization config for HappyLife"
        assert configs[0].get("enabled") is True

    def test_neutralizationConfigAlpina(self, db, mandateAlpina):
        from modules.features.neutralization.datamodelFeatureNeutralizer import DataNeutraliserConfig
        mid = mandateAlpina.get("id")
        instances = _getFeatureInstances(db, mid, "neutralization")
        assert instances
        iid = instances[0].get("id")
        configs = db.getRecordset(DataNeutraliserConfig, recordFilter={"featureInstanceId": iid})
        assert len(configs) >= 1, "No neutralization config for Alpina"


class TestDemoRemoveAndReload:

    def test_removeAndReload(self, db, demoConfig):
        """Remove all demo data, verify gone, then reload."""
        removeSummary = demoConfig.remove(db)
        assert len(removeSummary.get("errors", [])) == 0, f"Remove errors: {removeSummary['errors']}"

        mandates = db.getRecordset(Mandate, recordFilter={"name": "happylife"})
        assert len(mandates) == 0, "HappyLife mandate should be gone after remove"

        users = db.getRecordset(UserInDB, recordFilter={"username": "patrick.helvetia"})
        assert len(users) == 0, "User should be gone after remove"

        loadSummary = demoConfig.load(db)
        assert len(loadSummary.get("errors", [])) == 0, f"Reload errors: {loadSummary['errors']}"

        mandates = db.getRecordset(Mandate, recordFilter={"name": "happylife"})
        assert len(mandates) == 1, "HappyLife mandate should exist after reload"
