package dev.dinauer.maven.maven.core.snapshot.metadata;

import com.ctc.wstx.shaded.msv_core.util.LightStack;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import dev.dinauer.maven.maven.core.context.VersionContext;
import dev.dinauer.maven.maven.core.snapshot.*;
import dev.dinauer.maven.maven.core.snapshot.metadata.model.Snapshot;
import dev.dinauer.maven.maven.core.snapshot.metadata.model.SnapshotMetadata;
import dev.dinauer.maven.maven.core.snapshot.metadata.model.SnapshotVersion;
import dev.dinauer.maven.maven.core.snapshot.metadata.model.SnapshotVersioning;
import dev.dinauer.maven.maven.core.snapshot.metadata.utils.SnapshotComparator;
import dev.dinauer.maven.metadata.Metadata;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.InternalServerErrorException;
import org.apache.commons.lang3.Strings;

import java.util.List;
import java.util.stream.Stream;

@ApplicationScoped
public class SnapshotMetadataService
{
    private static final XmlMapper XML_MAPPER = new XmlMapper();

    @Inject
    SnapshotBundleRepo snapshotBundleRepo;

    public String generate(VersionContext versionContext)
    {
        try
        {
            return XML_MAPPER.writeValueAsString(generateMetadata(versionContext));
        }
        catch (JsonProcessingException e)
        {
            throw new InternalServerErrorException();
        }
    }

    private SnapshotMetadata generateMetadata(VersionContext versionContext)
    {
        SnapshotBundle latest = snapshotBundleRepo.latest(versionContext);
        Snapshot snapshot = new Snapshot(String.format("%s.%s", latest.getDate(), latest.getTime()), latest.getBuildNumber());
        List<SnapshotVersion> versions = toVersions(versionContext.plainVersion(), latest);
        return new SnapshotMetadata(versionContext.groupId(), versionContext.artifactId(), versionContext.version(), new SnapshotVersioning(snapshot, latest.getDate() + latest.getTime(), versions));
    }

    private List<SnapshotVersion> toVersions(String version, SnapshotBundle bundle)
    {
        SnapshotPom pom = bundle.getPom();
        if (pom != null)
        {
            SnapshotVersion pomVersion = new SnapshotVersion(null, "pom", formatValue(version, bundle.getDate(), bundle.getTime(), bundle.getBuildNumber()), bundle.getDateTime());
            return Stream.concat(bundle.getJars().stream().map(item -> jarToVersion(version, bundle, item)), Stream.of(pomVersion)).toList();
        }
        throw new InternalServerErrorException();
    }

    private SnapshotVersion jarToVersion(String version, SnapshotBundle bundle, SnapshotJar jar)
    {
        return new SnapshotVersion(jar.getClassifier(), "jar", formatValue(version, bundle.getDate(), bundle.getTime(), bundle.getBuildNumber()), bundle.getDateTime());
    }

    private String formatValue(String version, String date, String time, int buildNumber)
    {
        return String.format("%s-%s.%s-%s", version, date, time, buildNumber);
    }
}
