package p.studio.projectstate;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import p.studio.projects.ProjectReference;
import p.studio.projects.ProjectStudioPaths;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

final class ProjectLocalStudioStateServiceTest {
    @TempDir
    Path tempDir;

    @Test
    void savesAndLoadsSingleFileProjectLocalStudioState() {
        final ProjectLocalStudioStateService service = new ProjectLocalStudioStateService();
        final ProjectReference project = project("main");
        final ProjectLocalStudioState state = new ProjectLocalStudioState(
                ProjectLocalStudioState.CURRENT_VERSION,
                new ProjectLocalStudioState.ShellLayout(
                        new ProjectLocalStudioState.AssetsLayoutState(List.of(0.42d))),
                new ProjectLocalStudioState.OpenShellState("ASSETS"));

        service.save(project, state);

        assertTrue(Files.isRegularFile(ProjectStudioPaths.statePath(project)));
        assertEquals(state, service.load(project));
    }

    @Test
    void malformedStateFallsBackToDefaults() throws Exception {
        final ProjectLocalStudioStateService service = new ProjectLocalStudioStateService();
        final ProjectReference project = project("main");
        Files.createDirectories(ProjectStudioPaths.studioRoot(project));
        Files.writeString(ProjectStudioPaths.statePath(project), "{ not valid json");

        assertEquals(ProjectLocalStudioState.defaults(), service.load(project));
    }

    @Test
    void unsupportedVersionFallsBackToDefaults() throws Exception {
        final ProjectLocalStudioStateService service = new ProjectLocalStudioStateService();
        final ProjectReference project = project("main");
        Files.createDirectories(ProjectStudioPaths.studioRoot(project));
        Files.writeString(
                ProjectStudioPaths.statePath(project),
                """
                {
                  "version": 99
                }
                """);

        assertEquals(ProjectLocalStudioState.defaults(), service.load(project));
    }

    @Test
    void legacyEditorStateLoadsWithAssetsFallbackAndIgnoresEditorFields() throws Exception {
        final ProjectLocalStudioStateService service = new ProjectLocalStudioStateService();
        final ProjectReference project = project("main");
        Files.createDirectories(ProjectStudioPaths.studioRoot(project));
        Files.writeString(
                ProjectStudioPaths.statePath(project),
                """
                {
                  "version": 1,
                  "shellLayout": {
                    "editorLayout": {
                      "contentSplitDividers": [0.2, 0.8]
                    },
                    "assetsLayout": {
                      "contentSplitDividers": [0.42]
                    }
                  },
                  "openShellState": {
                    "selectedWorkspaceId": "EDITOR"
                  },
                  "editorRestoration": {
                    "openTabPaths": ["src/main.pbs"],
                    "activeTabPath": "src/main.pbs"
                  }
                }
                """);

        assertEquals(
                new ProjectLocalStudioState(
                        ProjectLocalStudioState.CURRENT_VERSION,
                        new ProjectLocalStudioState.ShellLayout(
                                new ProjectLocalStudioState.AssetsLayoutState(List.of(0.42d))),
                        new ProjectLocalStudioState.OpenShellState("ASSETS")),
                service.load(project));
    }

    private ProjectReference project(final String name) {
        final Path projectRoot = tempDir.resolve(name);
        return new ProjectReference("Main", "1.0.0", "pbs", 1, projectRoot);
    }
}
