package p.packer.services;

import p.packer.messages.assets.OutputCodecCatalog;
import p.packer.messages.assets.OutputFormatCatalog;
import p.packer.models.PackerCodecConfigurationField;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

final class PackerOutputContractCatalog {
    private PackerOutputContractCatalog() {
    }

    static OutputContractDefinition definitionFor(String outputFormat, OutputCodecCatalog selectedCodec) {
        final List<OutputCodecCatalog> availableCodecs = availableCodecsFor(outputFormat, selectedCodec);
        return new OutputContractDefinition(
                availableCodecs,
                availableCodecs.stream().collect(java.util.stream.Collectors.toMap(
                        codec -> codec,
                        codec -> fieldsFor(outputFormat, codec),
                        (left, right) -> left,
                        java.util.LinkedHashMap::new)));
    }

    static List<OutputCodecCatalog> availableCodecsFor(String outputFormat, OutputCodecCatalog selectedCodec) {
        final Set<OutputCodecCatalog> codecs = new LinkedHashSet<>();
        final OutputFormatCatalog formatCatalog = OutputFormatCatalog.fromManifestValue(outputFormat);
        if (formatCatalog != OutputFormatCatalog.UNKNOWN) {
            codecs.addAll(formatCatalog.availableCodecs());
        } else {
            final String normalizedFormat = Objects.requireNonNullElse(outputFormat, "").trim().toUpperCase(Locale.ROOT);
            if (normalizedFormat.startsWith("TILES/")
                    || normalizedFormat.startsWith("PALETTE/")
                    || normalizedFormat.startsWith("SOUND/")
                    || normalizedFormat.startsWith("AUDIO/")) {
                codecs.add(OutputCodecCatalog.NONE);
            }
        }

        final OutputCodecCatalog normalizedSelectedCodec = Objects.requireNonNullElse(selectedCodec, OutputCodecCatalog.UNKNOWN);
        if (normalizedSelectedCodec != OutputCodecCatalog.UNKNOWN) {
            codecs.add(normalizedSelectedCodec);
        }

        if (codecs.isEmpty()) {
            codecs.add(OutputCodecCatalog.NONE);
        }
        return List.copyOf(codecs);
    }

    private static List<PackerCodecConfigurationField> fieldsFor(String outputFormat, OutputCodecCatalog codec) {
        return List.of();
    }

    record OutputContractDefinition(
            List<OutputCodecCatalog> availableCodecs,
            Map<OutputCodecCatalog, List<PackerCodecConfigurationField>> codecConfigurationFieldsByCodec) {
    }
}
