"""
Basic verification tests for Phase 1-3 implementation.
Run with: python tests/test_phase123_basic.py
Requires: gateway running on localhost:8000
"""
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

print("=" * 60)
print("PHASE 1-3 BASIC VERIFICATION")
print("=" * 60)

errors = []
passes = []

def _check(label, condition, detail=""):
    if condition:
        passes.append(label)
        print(f"  [PASS] {label}")
    else:
        errors.append(f"{label}: {detail}")
        print(f"  [FAIL] {label} — {detail}")

# ── Phase 1: Data Models ──────────────────────────────────────────────────────
print("\n--- Phase 1: Data Models ---")

try:
    from modules.datamodels.datamodelUam import Mandate
    m = Mandate(name="test", label="test")
    _check("Mandate has isSystem field", hasattr(m, "isSystem"))
    _check("Mandate isSystem default False", m.isSystem is False)
    _check("Mandate no mandateType field", not hasattr(m, "mandateType"))
except Exception as e:
    errors.append(f"Phase 1 DataModel: {e}")
    print(f"  [FAIL] Phase 1 DataModel import: {e}")

try:
    from modules.datamodels.datamodelSubscription import SubscriptionStatusEnum, BUILTIN_PLANS, SubscriptionPlan
    _check("PENDING status exists", hasattr(SubscriptionStatusEnum, "PENDING"))
    _check("BUILTIN_PLANS has TRIAL_14D", "TRIAL_14D" in BUILTIN_PLANS)
    trial = BUILTIN_PLANS["TRIAL_14D"]
    _check("TRIAL_14D has maxDataVolumeMB", hasattr(trial, "maxDataVolumeMB"))
    _check("TRIAL_14D maxDataVolumeMB=1024", trial.maxDataVolumeMB == 1024)
    _check("TRIAL_14D has includedModules", hasattr(trial, "includedModules"))
    _check("TRIAL_14D includedModules=2", trial.includedModules == 2)
    _check("TRIAL_14D trialDays=14", trial.trialDays == 14)
except Exception as e:
    errors.append(f"Phase 1 Subscription: {e}")
    print(f"  [FAIL] Phase 1 Subscription: {e}")

# ── Phase 2: Scope Fields ─────────────────────────────────────────────────────
print("\n--- Phase 2: Scope Fields on Models ---")

try:
    from modules.datamodels.datamodelFiles import FileItem
    fi = FileItem(fileName="test.txt", mimeType="text/plain", fileHash="abc", fileSize=100)
    _check("FileItem has scope field", hasattr(fi, "scope"))
    _check("FileItem scope default=personal", fi.scope == "personal")
    _check("FileItem has neutralize field", hasattr(fi, "neutralize"))
    _check("FileItem neutralize default=False", fi.neutralize == False)
except Exception as e:
    errors.append(f"Phase 2 FileItem: {e}")
    print(f"  [FAIL] Phase 2 FileItem: {e}")

try:
    from modules.datamodels.datamodelDataSource import DataSource
    ds = DataSource(connectionId="c1", sourceType="sharepoint", path="/test", label="Test")
    _check("DataSource has scope field", hasattr(ds, "scope"))
    _check("DataSource scope default=personal", ds.scope == "personal")
    _check("DataSource has neutralize field", hasattr(ds, "neutralize"))
    _check("DataSource neutralize default=False", ds.neutralize == False)
except Exception as e:
    errors.append(f"Phase 2 DataSource: {e}")
    print(f"  [FAIL] Phase 2 DataSource: {e}")

try:
    from modules.datamodels.datamodelKnowledge import FileContentIndex
    fci = FileContentIndex(userId="u1", fileName="test.txt", mimeType="text/plain")
    _check("FileContentIndex has scope field", hasattr(fci, "scope"))
    _check("FileContentIndex scope default=personal", fci.scope == "personal")
    _check("FileContentIndex has neutralizationStatus", hasattr(fci, "neutralizationStatus"))
    _check("FileContentIndex neutralizationStatus default=None", fci.neutralizationStatus is None)
except Exception as e:
    errors.append(f"Phase 2 FileContentIndex: {e}")
    print(f"  [FAIL] Phase 2 FileContentIndex: {e}")

# ── Phase 2: RAG Scope Filtering ──────────────────────────────────────────────
print("\n--- Phase 2: RAG Scope Logic ---")

try:
    from modules.interfaces.interfaceDbKnowledge import KnowledgeObjects
    _check("KnowledgeObjects has _getScopedFileIds", hasattr(KnowledgeObjects, "_getScopedFileIds"))
    _check("KnowledgeObjects has _buildScopeFilter", hasattr(KnowledgeObjects, "_buildScopeFilter"))

    import inspect
    sig = inspect.signature(KnowledgeObjects._getScopedFileIds)
    params = list(sig.parameters.keys())
    _check("_getScopedFileIds has isSysAdmin param", "isSysAdmin" in params)

    sig2 = inspect.signature(KnowledgeObjects.semanticSearch)
    params2 = list(sig2.parameters.keys())
    _check("semanticSearch has scope param", "scope" in params2)
    _check("semanticSearch has isSysAdmin param", "isSysAdmin" in params2)
except Exception as e:
    errors.append(f"Phase 2 RAG: {e}")
    print(f"  [FAIL] Phase 2 RAG: {e}")

# ── Phase 3: Neutralization Methods ───────────────────────────────────────────
print("\n--- Phase 3: Neutralization Integration ---")

try:
    from modules.workflows.workflowManager import WorkflowManager
    _check("WorkflowManager has _neutralizePromptIfRequired", hasattr(WorkflowManager, "_neutralizePromptIfRequired"))
    _check("WorkflowManager has _rehydrateResponseIfNeeded", hasattr(WorkflowManager, "_rehydrateResponseIfNeeded"))

    import inspect
    sig_n = inspect.signature(WorkflowManager._neutralizePromptIfRequired)
    _check("_neutralizePromptIfRequired is async", inspect.iscoroutinefunction(WorkflowManager._neutralizePromptIfRequired))

    sig_r = inspect.signature(WorkflowManager._rehydrateResponseIfNeeded)
    _check("_rehydrateResponseIfNeeded is async", inspect.iscoroutinefunction(WorkflowManager._rehydrateResponseIfNeeded))
except Exception as e:
    errors.append(f"Phase 3 WorkflowManager: {e}")
    print(f"  [FAIL] Phase 3 WorkflowManager: {e}")

# ── Phase 3: Fail-Safe Logic ──────────────────────────────────────────────────
print("\n--- Phase 3: Fail-Safe Logic ---")

try:
    import ast
    with open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
              "modules", "workflows", "methods", "methodContext", "actions", "neutralizeData.py"), "r") as f:
        source = f.read()
    _check("neutralizeData.py has 'SKIPPING' fail-safe", "SKIPPING" in source)
    _check("neutralizeData.py has 'do NOT pass original' comment", "do NOT pass original" in source.lower() or "not passing original" in source.lower())
    _check("neutralizeData.py uses continue for skip", "continue" in source)
except Exception as e:
    errors.append(f"Phase 3 Fail-Safe: {e}")
    print(f"  [FAIL] Phase 3 Fail-Safe: {e}")

# ── Phase 2: Route Endpoints ──────────────────────────────────────────────────
print("\n--- Phase 2: API Endpoints ---")

try:
    import ast
    with open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
              "modules", "routes", "routeDataFiles.py"), "r") as f:
        source = f.read()
    _check("routeDataFiles has PATCH scope endpoint", "updateFileScope" in source)
    _check("routeDataFiles has PATCH neutralize endpoint", "updateFileNeutralize" in source)
    _check("routeDataFiles checks global sysAdmin", "hasSysAdminRole" in source or "sysadmin" in source.lower())
except Exception as e:
    errors.append(f"Phase 2 Routes: {e}")
    print(f"  [FAIL] Phase 2 Routes: {e}")

# ── Phase 1: Store Endpoints ──────────────────────────────────────────────────
print("\n--- Phase 1: Store Endpoints ---")

try:
    with open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
              "modules", "routes", "routeStore.py"), "r") as f:
        source = f.read()
    _check("routeStore has listUserMandates", "listUserMandates" in source or "list_user_mandates" in source)
    _check("routeStore has getSubscriptionInfo", "getSubscriptionInfo" in source or "get_subscription_info" in source)
    _check("routeStore has orphan control", "orphan" in source.lower() or "last" in source.lower())
except Exception as e:
    errors.append(f"Phase 1 Store: {e}")
    print(f"  [FAIL] Phase 1 Store: {e}")

# ── Phase 1: Provisioning ─────────────────────────────────────────────────────
print("\n--- Phase 1: Provisioning ---")

try:
    with open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
              "modules", "interfaces", "interfaceDbApp.py"), "r") as f:
        source = f.read()
    _check("interfaceDbApp has _provisionMandateForUser", "_provisionMandateForUser" in source)
    _check("interfaceDbApp has _activatePendingSubscriptions", "_activatePendingSubscriptions" in source)
    _check("interfaceDbApp has deleteMandate cascade", "deleteMandate" in source and "cascade" in source.lower())
except Exception as e:
    errors.append(f"Phase 1 Provisioning: {e}")
    print(f"  [FAIL] Phase 1 Provisioning: {e}")

# ── Phase 1: Registration Routes ──────────────────────────────────────────────
print("\n--- Phase 1: Registration ---")

try:
    with open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
              "modules", "routes", "routeSecurityLocal.py"), "r") as f:
        source = f.read()
    _check("routeSecurityLocal has registrationType", "registrationType" in source)
    _check("routeSecurityLocal has companyName", "companyName" in source)
    _check("routeSecurityLocal has onboarding endpoint", "onboarding" in source)
except Exception as e:
    errors.append(f"Phase 1 Registration: {e}")
    print(f"  [FAIL] Phase 1 Registration: {e}")

# ── Fix 1: OnboardingWizard Integration ────────────────────────────────────────
print("\n--- Fix 1: OnboardingWizard Integration ---")

try:
    loginPath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
                             "..", "frontend_nyla", "src", "pages", "Login.tsx")
    with open(loginPath, "r", encoding="utf-8") as f:
        source = f.read()
    _check("Login.tsx imports OnboardingWizard", "OnboardingWizard" in source)
    _check("Login.tsx has showOnboardingWizard state", "showOnboardingWizard" in source)
    _check("Login.tsx checks isNewUser", "isNewUser" in source)
except Exception as e:
    errors.append(f"Fix 1: {e}")
    print(f"  [FAIL] Fix 1: {e}")

# ── Fix 2: CommCoach UDB Integration ──────────────────────────────────────────
print("\n--- Fix 2: CommCoach UDB Integration ---")

try:
    dossierPath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
                               "..", "frontend_nyla", "src", "pages", "views", "commcoach", "CommcoachDossierView.tsx")
    with open(dossierPath, "r", encoding="utf-8") as f:
        source = f.read()
    _check("CommCoach imports UnifiedDataBar", "UnifiedDataBar" in source)
    _check("CommCoach imports FilesTab", "FilesTab" in source)
    _check("CommCoach no longer imports getDocumentsApi", "getDocumentsApi" not in source)
    _check("CommCoach has UDB sidebar", "udbSidebar" in source or "UnifiedDataBar" in source)
except Exception as e:
    errors.append(f"Fix 2: {e}")
    print(f"  [FAIL] Fix 2: {e}")

# ── Fix 3: Neutralization Backend Endpoints ───────────────────────────────────
print("\n--- Fix 3: Neutralization Backend Endpoints ---")

try:
    routePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
                             "modules", "features", "neutralization", "routeFeatureNeutralizer.py")
    with open(routePath, "r") as f:
        source = f.read()
    _check("Neutralization has deleteAttribute endpoint", "deleteAttribute" in source or "delete_attribute" in source)
    _check("Neutralization has retrigger endpoint", "retrigger" in source)
    _check("Neutralization has single attribute delete", "single" in source or "attributeId" in source)
except Exception as e:
    errors.append(f"Fix 3: {e}")
    print(f"  [FAIL] Fix 3: {e}")

# ── Fix 4: Central AI Neutralization ──────────────────────────────────────────
print("\n--- Fix 4: Central AI Neutralization ---")

try:
    aiPath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
                          "modules", "serviceCenter", "services", "serviceAi", "mainServiceAi.py")
    with open(aiPath, "r") as f:
        source = f.read()
    _check("AiService has _shouldNeutralize", "_shouldNeutralize" in source)
    _check("AiService has _neutralizeRequest", "_neutralizeRequest" in source)
    _check("AiService has _rehydrateResponse", "_rehydrateResponse" in source)
    _check("callAi uses neutralization", "_shouldNeutralize" in source and "_neutralizeRequest" in source)
except Exception as e:
    errors.append(f"Fix 4: {e}")
    print(f"  [FAIL] Fix 4: {e}")

# ── Fix 5: Voice Settings User Level ──────────────────────────────────────────
print("\n--- Fix 5: Voice Settings User Level ---")

try:
    from modules.datamodels.datamodelUam import UserVoicePreferences
    uvp = UserVoicePreferences(userId="u1")
    _check("UserVoicePreferences model exists", True)
    _check("UserVoicePreferences has sttLanguage", hasattr(uvp, "sttLanguage"))
    _check("UserVoicePreferences default sttLanguage=de-DE", uvp.sttLanguage == "de-DE")
    _check("UserVoicePreferences has ttsVoice", hasattr(uvp, "ttsVoice"))
except Exception as e:
    errors.append(f"Fix 5: {e}")
    print(f"  [FAIL] Fix 5: {e}")

try:
    voiceUserPath = os.path.join(
        os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
        "modules", "routes", "routeVoiceUser.py",
    )
    with open(voiceUserPath, "r") as f:
        source = f.read()
    _check("Voice preferences GET endpoint", '"/preferences"' in source and "getVoicePreferences" in source)
    _check("Voice preferences PUT endpoint", "updateVoicePreferences" in source)
except Exception as e:
    errors.append(f"Fix 5 Routes: {e}")
    print(f"  [FAIL] Fix 5 Routes: {e}")

# ── Fix 6: RAG mandate-wide scope ─────────────────────────────────────────────
print("\n--- Fix 6: RAG mandate-wide scope ---")

try:
    knowledgePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
                                  "modules", "serviceCenter", "services", "serviceKnowledge", "mainServiceKnowledge.py")
    with open(knowledgePath, "r") as f:
        source = f.read()
    _check("buildAgentContext passes mandateId to semanticSearch", "mandateId=mandateId" in source)
    _check("buildAgentContext has isSysAdmin param", "isSysAdmin" in source)
except Exception as e:
    errors.append(f"Fix 6: {e}")
    print(f"  [FAIL] Fix 6: {e}")

# ── Summary ───────────────────────────────────────────────────────────────────
print("\n" + "=" * 60)
print(f"RESULTS: {len(passes)} passed, {len(errors)} failed")
print("=" * 60)

if errors:
    print("\nFAILURES:")
    for e in errors:
        print(f"  - {e}")
    sys.exit(1)
else:
    print("\nALL CHECKS PASSED!")
    sys.exit(0)
