namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;

public sealed class LegacyOperatorSettingsNativeContractTests
{
    private static readonly string RepositoryRoot = FindRepositoryRoot();
    private static readonly string AppRoot = Path.Combine(
        RepositoryRoot,
        "src",
        "MBN_STOCK_WEBVIEW.LegacyParityApp");
    private static readonly string Window = File.ReadAllText(
        Path.Combine(AppRoot, "MainWindow.xaml.cs"));
    private static readonly string Settings = File.ReadAllText(
        Path.Combine(AppRoot, "MainWindow.Settings.cs"));
    private static readonly string FolderPicker = File.ReadAllText(
        Path.Combine(AppRoot, "MainWindow.BackgroundPicker.cs"));
    private static readonly string Playout = File.ReadAllText(
        Path.Combine(AppRoot, "MainWindow.Playout.cs"));

    [Fact]
    public void FolderPathsComeOnlyFromTheWindowOwnedNativePicker()
    {
        Assert.Contains(
            "var initialDirectory = ResolveOperatorFolderPickerStartDirectory(kind)",
            Settings,
            StringComparison.Ordinal);
        Assert.Contains("await PickOperatorFolderAsync(", Settings,
            StringComparison.Ordinal);
        Assert.Contains("LegacyFileDialog.ShowFolder(", FolderPicker,
            StringComparison.Ordinal);
        Assert.Contains("WindowNative.GetWindowHandle(this)", FolderPicker,
            StringComparison.Ordinal);
        Assert.Contains("FileOpenOptions.PickFolders", FolderPicker,
            StringComparison.Ordinal);
        Assert.Contains("FileOpenOptions.ForceFileSystem", FolderPicker,
            StringComparison.Ordinal);
        Assert.Contains("FileOpenOptions.PathMustExist", FolderPicker,
            StringComparison.Ordinal);
        Assert.Contains("FileOpenOptions.NoDereferenceLinks", FolderPicker,
            StringComparison.Ordinal);
        Assert.Contains("dialog.SetFolder(initialFolder);", FolderPicker,
            StringComparison.Ordinal);
        Assert.Contains("dialog.SetDefaultFolder(initialFolder);", FolderPicker,
            StringComparison.Ordinal);
        Assert.Contains("selectedPath", Settings, StringComparison.Ordinal);
        Assert.Contains("LegacyOperatorFolderValidator.TryValidate(", Settings,
            StringComparison.Ordinal);
        Assert.DoesNotContain("PickerLocationId.ComputerFolder", Settings,
            StringComparison.Ordinal);
        Assert.DoesNotContain("intent.Path", Settings, StringComparison.Ordinal);
        Assert.DoesNotContain("choose.Path", Settings, StringComparison.Ordinal);
    }

    [Fact]
    public void FolderPickerStartsAtTheLatestSavedPathOrItsNearestExistingParent()
    {
        var resolver = Slice(
            Settings,
            "private string? ResolveOperatorFolderPickerStartDirectory(",
            "private static string ResolveOperatorFolderPickerTitle(");

        Assert.Contains("_operatorSettings.SceneDirectory", resolver,
            StringComparison.Ordinal);
        Assert.Contains("_operatorSettings.ResourceDirectory", resolver,
            StringComparison.Ordinal);
        Assert.Contains("_operatorSettings.BackgroundDirectory", resolver,
            StringComparison.Ordinal);
        Assert.DoesNotContain("_appliedOperatorSettings", resolver,
            StringComparison.Ordinal);
        Assert.Contains("Path.Combine(AppContext.BaseDirectory, \"Cuts\")", resolver,
            StringComparison.Ordinal);
        Assert.Contains("Path.Combine(AppContext.BaseDirectory, \"Res\")", resolver,
            StringComparison.Ordinal);
        Assert.Contains("ResolveAutomaticBackgroundDirectory()", resolver,
            StringComparison.Ordinal);
        Assert.Contains("FindNearestExistingDirectory(preferredPath)", resolver,
            StringComparison.Ordinal);
        Assert.Contains("candidate = candidate.Parent", resolver,
            StringComparison.Ordinal);
        Assert.Contains("FindNearestExistingDirectory(AppContext.BaseDirectory)", resolver,
            StringComparison.Ordinal);
    }

    [Fact]
    public void FolderPickerTitleAndButtonRemainCompatibleWithTheLocalStateSmoke()
    {
        Assert.Contains("\"폴더 선택 - 디자인\"", Settings, StringComparison.Ordinal);
        Assert.Contains("\"폴더 선택 - 설정\"", Settings, StringComparison.Ordinal);
        Assert.Contains("\"폴더 선택 - 배경\"", Settings, StringComparison.Ordinal);
        Assert.Contains("dialog.SetOkButtonLabel(\"폴더 선택\")", FolderPicker,
            StringComparison.Ordinal);
    }

    [Fact]
    public void SelectedFoldersAreLoadedAtStartupAndAppliedOnlyAtCompositionBoundaries()
    {
        Assert.Contains("_operatorSettingsStore.Load()", Window, StringComparison.Ordinal);
        Assert.Contains("_appliedOperatorSettings = operatorSettingsLoad.Settings", Window,
            StringComparison.Ordinal);
        Assert.Contains("ResolveFromResourceDirectory(", Window, StringComparison.Ordinal);
        Assert.Contains("preferLegacyOverride: selectedLegacyDatabaseIni is not null", Window,
            StringComparison.Ordinal);
        Assert.Contains(
            "operatorSceneDirectory: _appliedOperatorSettings.SceneDirectory",
            Playout,
            StringComparison.Ordinal);
        Assert.Contains(
            "operatorBackgroundDirectory:",
            Playout,
            StringComparison.Ordinal);
        Assert.Contains("_appliedOperatorSettings.BackgroundDirectory", Playout,
            StringComparison.Ordinal);
        Assert.DoesNotContain("InitializePlayoutRuntime();", Settings, StringComparison.Ordinal);
        Assert.DoesNotContain("CreateLegacyExecutableDefault(", Settings,
            StringComparison.Ordinal);
    }

    [Fact]
    public void GateAUsesOnlyThePinnedJsonDatabaseProfile()
    {
        var databaseComposition = Slice(
            Window,
            "string? initializationError = null;",
            "DataQueryExecutor.Configure(_databaseRuntime.Executor);");
        var gateA = RequiredIndex(
            databaseComposition,
            "_playoutLaunchAuthorization.IsGateA");
        var pinnedJson = RequiredIndex(
            databaseComposition,
            "DatabaseRuntime.CreateDefault()",
            gateA);
        var legacyIni = RequiredIndex(
            databaseComposition,
            "DatabaseRuntime.CreateLegacyExecutableDefault(",
            pinnedJson);

        Assert.True(gateA < pinnedJson);
        Assert.True(pinnedJson < legacyIni);
    }

    [Fact]
    public void SettingsWritesAreGateABlockedAndDoNotWaitForDatabaseHealthActivity()
    {
        var process = Slice(
            Window,
            "private async Task ProcessIntentAsync(LegacyUiIntent intent)",
            "private static bool IsOrderedPlayoutIntent");
        var gateABlock = RequiredIndex(process, "IsPersistentWriteIntent(intent)");
        var settingsDispatch = RequiredIndex(
            process,
            "await HandleOperatorSettingsIntentAsync(",
            gateABlock);
        var databaseWait = RequiredIndex(
            process,
            "await AcquirePriorityDatabaseActivityAsync(_lifetimeCancellation.Token)");

        Assert.True(gateABlock < settingsDispatch);
        Assert.True(settingsDispatch < databaseWait);
        Assert.Contains("HandleOperatorSettingsIntentAsync(", process,
            StringComparison.Ordinal);
        Assert.Contains("LegacyChooseOperatorFolderIntent", Playout,
            StringComparison.Ordinal);
        Assert.Contains("LegacyResetOperatorFolderIntent", Playout,
            StringComparison.Ordinal);
        Assert.Contains("LegacySetOperatorNavigationExpandedIntent", Playout,
            StringComparison.Ordinal);
        Assert.Contains("LegacySetOperatorAppearanceIntent", Playout,
            StringComparison.Ordinal);
        Assert.Contains("ReconcileRejectedOperatorSettingsIntent(", process,
            StringComparison.Ordinal);
    }

    [Fact]
    public void AppearanceIntentIsPersistedRoutedAndProjectedAsOneClosedUpdate()
    {
        Assert.Contains(
            "case LegacySetOperatorAppearanceIntent appearance:",
            Settings,
            StringComparison.Ordinal);
        Assert.Contains("ColorTheme = appearance.ColorTheme", Settings,
            StringComparison.Ordinal);
        Assert.Contains("ViewMode = appearance.ViewMode", Settings,
            StringComparison.Ordinal);
        Assert.Contains("StartWorkspace = appearance.StartWorkspace", Settings,
            StringComparison.Ordinal);
        Assert.Contains("_operatorSettings.ColorTheme", Settings,
            StringComparison.Ordinal);
        Assert.Contains("_operatorSettings.ViewMode", Settings,
            StringComparison.Ordinal);
        Assert.Contains("_operatorSettings.StartWorkspace", Settings,
            StringComparison.Ordinal);
        Assert.Contains("LegacySetOperatorAppearanceIntent", Window,
            StringComparison.Ordinal);
    }

    [Fact]
    public void SettingsStateIsProjectedWithoutPublishingFullNativePaths()
    {
        Assert.Contains("operatorSettings: CreateOperatorSettingsSnapshot()", Window,
            StringComparison.Ordinal);
        Assert.Contains("AbbreviatedPath", Settings, StringComparison.Ordinal);
        Assert.DoesNotContain("CanonicalPath,\n        _operatorSettingsMessage", Settings,
            StringComparison.Ordinal);
        Assert.Contains("DatabasePollingSeconds: (int)DatabaseHealthPollingInterval.TotalSeconds",
            Settings,
            StringComparison.Ordinal);
    }

    [Fact]
    public void FailedSettingsSaveRevisionsTheSnapshotToUndoOptimisticNavigation()
    {
        Assert.Contains(
            "if (!result.Succeeded || result.SavedSettings is null)",
            Settings,
            StringComparison.Ordinal);
        Assert.Contains(
            "Interlocked.Increment(ref _operatorSettingsRevision);",
            Settings,
            StringComparison.Ordinal);
    }

    [Fact]
    public void SettingsUsesConciseRoutineStatusCopy()
    {
        var cancelledPicker = Slice(
            Settings,
            "if (selectedPath is null)",
            "cancellationToken.ThrowIfCancellationRequested();");

        Assert.DoesNotContain(
            "SetOperatorSettingsMessage",
            cancelledPicker,
            StringComparison.Ordinal);
        Assert.Contains("\"저장됨\"", Settings, StringComparison.Ordinal);
        Assert.Contains("\"저장됨 · 재시작 필요\"", Settings, StringComparison.Ordinal);
        Assert.Contains("\"초기화됨 · 재시작 필요\"", Settings, StringComparison.Ordinal);
        Assert.Contains("\"앱 기본값\"", Settings, StringComparison.Ordinal);
        Assert.Contains("\"자동\"", Settings, StringComparison.Ordinal);
        Assert.Contains("\"사용 가능\"", Settings, StringComparison.Ordinal);
        Assert.DoesNotContain("외부 영상", Settings, StringComparison.Ordinal);
        Assert.DoesNotContain("핵심 자산 확인됨", Settings, StringComparison.Ordinal);
    }

    private static string Slice(string value, string start, string end)
    {
        var startIndex = RequiredIndex(value, start);
        var endIndex = RequiredIndex(value, end, startIndex + start.Length);
        return value[startIndex..endIndex];
    }

    private static int RequiredIndex(string value, string needle, int startIndex = 0)
    {
        var index = value.IndexOf(needle, startIndex, StringComparison.Ordinal);
        Assert.True(index >= 0, $"Required marker was not found: {needle}");
        return index;
    }

    private static string FindRepositoryRoot()
    {
        var directory = new DirectoryInfo(AppContext.BaseDirectory);
        while (directory is not null)
        {
            if (File.Exists(Path.Combine(directory.FullName, "MBN_STOCK_WEBVIEW.sln")))
            {
                return directory.FullName;
            }

            directory = directory.Parent;
        }

        throw new DirectoryNotFoundException("Repository root was not found.");
    }
}
