package io.quarkus.devtools.testing.codestarts;

import static io.quarkus.platform.catalog.processor.ExtensionProcessor.getBuiltWithQuarkusCore;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import io.quarkus.devtools.codestarts.DataKey;
import io.quarkus.devtools.codestarts.quarkus.QuarkusCodestartCatalog;
import io.quarkus.devtools.codestarts.quarkus.QuarkusCodestartCatalog.Language;
import io.quarkus.devtools.project.BuildTool;
import io.quarkus.devtools.project.extensions.Extensions;
import io.quarkus.devtools.testing.FakeExtensionCatalog;
import io.quarkus.maven.ArtifactCoords;
import io.quarkus.maven.ArtifactKey;
import io.quarkus.platform.descriptor.loader.json.ResourceLoaders;
import io.quarkus.registry.catalog.Extension;
import io.quarkus.registry.catalog.ExtensionCatalog;
import io.quarkus.registry.catalog.json.JsonCatalogMapperHelper;
import io.quarkus.registry.catalog.json.JsonExtension;
import io.quarkus.registry.catalog.json.JsonExtensionCatalog;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

public class QuarkusCodestartTestBuilder {
    public Map<String, Object> data = new HashMap<>();
    public Collection<String> artifacts = new ArrayList<>();
    BuildTool buildTool;
    Set<String> codestarts = new HashSet<>();
    Set<Language> languages;
    QuarkusCodestartCatalog quarkusCodestartCatalog;
    ExtensionCatalog extensionCatalog;
    Collection<ArtifactCoords> extensions = new ArrayList<>();

    public QuarkusCodestartTestBuilder codestarts(String... codestarts) {
        this.codestarts = new HashSet<>(Arrays.asList(codestarts));
        return this;
    }

    public QuarkusCodestartTestBuilder languages(Language... languages) {
        this.languages = new HashSet<>(Arrays.asList(languages));
        return this;
    }

    public QuarkusCodestartTestBuilder buildTool(BuildTool buildTool) {
        this.buildTool = buildTool;
        return this;
    }

    public QuarkusCodestartTestBuilder putData(String key, Object value) {
        this.data.put(key, value);
        return this;
    }

    public QuarkusCodestartTestBuilder putData(DataKey key, Object value) {
        this.data.put(key.key(), value);
        return this;
    }

    public QuarkusCodestartTestBuilder extensions(Collection<ArtifactCoords> extensions) {
        this.extensions.addAll(extensions);
        return this;
    }

    public QuarkusCodestartTestBuilder extension(ArtifactCoords extension) {
        this.extensions.add(extension);
        return this;
    }

    public QuarkusCodestartTestBuilder extension(ArtifactKey extension) {
        this.extensions.add(Extensions.toCoords(extension, null));
        return this;
    }

    public QuarkusCodestartTestBuilder addArtifacts(Collection<String> artifacts) {
        this.artifacts = artifacts;
        return this;
    }

    public QuarkusCodestartTestBuilder quarkusCodestartCatalog(QuarkusCodestartCatalog quarkusCodestartCatalog) {
        this.quarkusCodestartCatalog = quarkusCodestartCatalog;
        return this;
    }

    public QuarkusCodestartTestBuilder extensionCatalog(ExtensionCatalog extensionCatalog) {
        this.extensionCatalog = extensionCatalog;
        return this;
    }

    public QuarkusCodestartTestBuilder standaloneExtensionCatalog() {
        final JsonExtensionCatalog catalog = FakeExtensionCatalog.newFakeExtensionCatalog();
        final ArrayList<Extension> extensions = new ArrayList<>();
        try {
            String quarkusVersion = null;
            catalog.setQuarkusCoreVersion(null);
            for (URL url : Collections
                    .list(Thread.currentThread().getContextClassLoader().getResources("META-INF/quarkus-extension.yaml"))) {
                final ObjectMapper mapper = JsonCatalogMapperHelper.initMapper(new YAMLMapper());
                final JsonExtension extension = ResourceLoaders.processAsPath(url, path -> {
                    try {
                        return JsonCatalogMapperHelper.deserialize(mapper, path, JsonExtension.class);
                    } catch (IOException e) {
                        throw new UncheckedIOException(e);
                    }
                });
                extensions.add(extension);
                if (catalog.getQuarkusCoreVersion() == null) {
                    catalog.setQuarkusCoreVersion(getBuiltWithQuarkusCore(extension));
                }
            }

            Objects.requireNonNull(catalog.getQuarkusCoreVersion(), "quarkus version not found in extensions");
            catalog.setExtensions(extensions);
            catalog.setMetadata(new HashMap<>());
            this.extensionCatalog = catalog;
        } catch (IOException e) {
            throw new IllegalStateException("Error while reading standalone extension catalog", e);
        }
        return this;
    }

    public QuarkusCodestartTest build() {
        return new QuarkusCodestartTest(this);
    }
}

@@ -531,29 +531,28 @@
 ect.
-extensions.Extensions
+QuarkusProjectHelper
 ;%0Aim
@@ -580,20 +580,27 @@
 ols.
-testing.Fake
+project.extensions.
 Exte
@@ -596,39 +596,33 @@
 nsions.Extension
-Catalog
+s
 ;%0Aimport io.quar
@@ -3609,262 +3609,124 @@
     
-final JsonExtensionCatalog catalog = FakeExtensionCatalog.newFakeExtensionCatalog();%0A        final ArrayList%3CExtension%3E extensions = new ArrayList%3C%3E();%0A        try %7B%0A            String quarkusVersion = null;%0A            catalog.setQuarkusCoreVersion(null
+try %7B%0A            String quarkusVersion = null;%0A            final ArrayList%3CExtension%3E extensions = new ArrayList%3C%3E(
 );%0A 
@@ -4422,39 +4422,22 @@
 if (
-catalog.getQ
+q
 uarkus
-Core
 Version
-()
  == 
@@ -4468,38 +4468,25 @@
     
-catalog.setQ
+q
 uarkus
-Core
 Version
-(
+ = 
 getB
@@ -4515,17 +4515,16 @@
 tension)
-)
 ;%0A      
@@ -4545,25 +4545,24 @@
           %7D%0A
-%0A
             
@@ -4588,39 +4588,22 @@
 ull(
-catalog.getQ
+q
 uarkus
-Core
 Version
-()
 , %22q
@@ -4660,90 +4660,454 @@
     
-catalog.setExtensions(extensions);%0A            catalog.setMetadata(new HashMap%3C%3E()
+final ExtensionCatalog extensionCatalog = QuarkusProjectHelper%0A                    .getExtensionCatalog(quarkusVersion);%0A            if (!(extensionCatalog instanceof JsonExtensionCatalog)) %7B%0A                throw new IllegalStateException(%22Problem with the given ExtensionCatalog type%22);%0A            %7D%0A            extensions.addAll(extensionCatalog.getExtensions());%0A            ((JsonExtensionCatalog) extensionCatalog).setExtensions(extensions
 );%0A 
@@ -5141,17 +5141,26 @@
 talog = 
-c
+extensionC
 atalog;%0A

Use quarkus-bom catalog in QuarkusCodestartTest with standaloneExtensionCatalog