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

import dev.dinauer.maven.event.Event;
import dev.dinauer.maven.event.EventType;
import dev.dinauer.maven.event.Resource;
import dev.dinauer.maven.event.repo.EventRepo;
import dev.dinauer.maven.maven.core.context.ReleaseContext;
import dev.dinauer.maven.maven.core.context.SnapshotContext;
import io.quarkus.security.identity.SecurityIdentity;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.WebApplicationException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.NotImplementedException;

import java.nio.charset.StandardCharsets;
import java.time.ZonedDateTime;

@ApplicationScoped
public class SnapshotPomService
{
    @Inject
    SnapshotPomRepo snapshotPomRepo;

    @Inject
    EventRepo eventRepo;

    @Inject
    SnapshotBundleService snapshotBundleService;

    @Inject
    SecurityIdentity securityIdentity;

    public void store(SnapshotContext snapshotContext, byte[] body)
    {
        SnapshotBundle snapshotBundle = snapshotBundleService.findOrCreate(snapshotContext);
        SnapshotPom snapshotPom = snapshotPomRepo.find(snapshotBundle);
        if (snapshotPom == null)
        {
            create(snapshotBundle, body);
            createEvent(snapshotContext);
            snapshotBundle.setUpdatedAt(ZonedDateTime.now());
        }
        else
        {
            throw new WebApplicationException(501);
        }
    }

    public String find(SnapshotContext snapshotContext)
    {
        SnapshotBundle snapshotBundle = snapshotBundleService.require(snapshotContext);
        return snapshotPomRepo.require(snapshotBundle).getPom();
    }

    public String findHash(SnapshotContext snapshotContext)
    {
        SnapshotBundle snapshotBundle = snapshotBundleService.require(snapshotContext);
        SnapshotPom snapshotPom = snapshotPomRepo.require(snapshotBundle);
        return switch (snapshotContext.extensions().hashExt().orElseThrow())
        {
            case MD5 -> snapshotPom.getMd5();
            case SHA1 -> snapshotPom.getSha1();
            default -> throw new IllegalStateException("Unexpected value: " + snapshotContext.extensions().hashExt());
        };
    }

    private void create(SnapshotBundle bundle, byte[] content)
    {
        SnapshotPom snapshotPom = new SnapshotPom();
        snapshotPom.setSnapshotBundle(bundle);
        snapshotPom.setPom(new String(content, StandardCharsets.UTF_8));
        snapshotPom.setMd5(DigestUtils.md5Hex(content));
        snapshotPom.setSha1(DigestUtils.sha1Hex(content));
        snapshotPomRepo.persist(snapshotPom);
    }

    private void createEvent(SnapshotContext snapshotContext)
    {
        eventRepo.persist(new Event().setUserId(securityIdentity.getPrincipal().getName()).setType(EventType.UPLOAD).setTimestamp(ZonedDateTime.now()).setResource(new Resource().setGroupId(snapshotContext.groupId()).setArtifactId(snapshotContext.artifactId()).setVersion(snapshotContext.plainVersion()).setSnapshot(true)));
    }
}
