package p.studio.projectsessions;

import p.studio.execution.StudioExecutionSessionService;
import p.studio.lsp.api.LspServerLifecycle;
import p.studio.lsp.messages.LspServerConfiguration;
import p.studio.projects.ProjectReference;
import p.studio.projectstate.ProjectLocalStudioSetupService;
import p.studio.projectstate.ProjectLocalStudioStateService;

import java.util.Objects;

public final class StudioProjectSessionFactory {
    private final ProjectLocalStudioStateService projectLocalStudioStateService;
    private final ProjectLocalStudioSetupService projectLocalStudioSetupService;
    private final LspServerLifecycle lspServerLifecycle;

    public StudioProjectSessionFactory(final LspServerLifecycle lspServerLifecycle) {
        this(
                new ProjectLocalStudioStateService(),
                new ProjectLocalStudioSetupService(),
                Objects.requireNonNull(lspServerLifecycle, "lspServerLifecycle"));
    }

    StudioProjectSessionFactory(
            final ProjectLocalStudioStateService projectLocalStudioStateService,
            final ProjectLocalStudioSetupService projectLocalStudioSetupService,
            final LspServerLifecycle lspServerLifecycle) {
        this.projectLocalStudioStateService = Objects.requireNonNull(projectLocalStudioStateService, "projectLocalStudioStateService");
        this.projectLocalStudioSetupService = Objects.requireNonNull(projectLocalStudioSetupService, "projectLocalStudioSetupService");
        this.lspServerLifecycle = Objects.requireNonNull(lspServerLifecycle, "lspServerLifecycle");
    }

    public StudioProjectSession open(final ProjectReference projectReference) {
        final ProjectReference target = Objects.requireNonNull(projectReference, "projectReference");
        final var setup = projectLocalStudioSetupService.load(target);
        final var state = projectLocalStudioStateService.load(target);
        lspServerLifecycle.bootServer(LspServerConfiguration.defaults(), target.toLspProjectContext());
        return new StudioProjectSession(
                target,
                projectLocalStudioStateService,
                setup,
                new StudioExecutionSessionService(),
                lspServerLifecycle,
                state);
    }
}
