package p.studio.projects;

import p.studio.compiler.FrontendRegistryService;
import p.studio.compiler.models.FrontendSpec;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

public final class ProjectLanguageCatalogService {
    public List<ProjectLanguageTemplate> listLanguageTemplates() {
        return FrontendRegistryService.listFrontendSpecs().stream()
                .map(this::toTemplate)
                .sorted(Comparator.comparing(ProjectLanguageTemplate::languageId, String.CASE_INSENSITIVE_ORDER))
                .toList();
    }

    public ProjectLanguageTemplate getDefaultTemplate() {
        return listLanguageTemplates().stream()
                .findFirst()
                .orElseThrow(() -> new IllegalStateException("no frontend languages are registered"));
    }

    private ProjectLanguageTemplate toTemplate(FrontendSpec frontendSpec) {
        final List<String> sourceRoots = frontendSpec.getSourceRoots().stream()
                .sorted(String.CASE_INSENSITIVE_ORDER)
                .toList();
        final List<ProjectLanguageTemplate.StdlibOption> stdlibOptions = frontendSpec.getStdlibVersions().stream()
                .map(stdlib -> new ProjectLanguageTemplate.StdlibOption(stdlib.version(), stdlib.type()))
                .sorted(Comparator.comparingInt(ProjectLanguageTemplate.StdlibOption::version))
                .toList();
        final ProjectLanguageTemplate.StdlibOption defaultStdlib = stdlibOptions.stream()
                .filter(option -> option.type() == FrontendSpec.StdlibType.DEFAULT)
                .findFirst()
                .or(() -> stdlibOptions.stream().findFirst())
                .orElse(new ProjectLanguageTemplate.StdlibOption(1, FrontendSpec.StdlibType.DEFAULT));
        final String defaultSourceRoot = sourceRoots.stream()
                .findFirst()
                .orElse("src");
        return new ProjectLanguageTemplate(
                Objects.requireNonNull(frontendSpec.getLanguageId(), "frontendSpec.languageId"),
                stdlibOptions,
                defaultStdlib,
                sourceRoots,
                defaultSourceRoot);
    }
}
