package io.cameleer.server.app.web;

import io.cameleer.server.core.runtime.AppService;
import io.cameleer.server.core.runtime.AppVersion;
import io.cameleer.server.core.storage.ArtifactCoordinates;
import io.cameleer.server.core.storage.ArtifactStore;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
import java.util.UUID;

/**
 * Token-validated artifact download endpoint hit by the cameleer-runtime-loader
 * init container. Auth is the HMAC sig + exp on the URL — NOT JWT/bootstrap
 * token. permitAll'd in SecurityConfig because all auth is in the controller.
 */
@RestController
@RequestMapping("/api/v1/artifacts")
public class ArtifactDownloadController {

    private final AppService appService;
    private final ArtifactStore artifactStore;
    private final ArtifactDownloadTokenSigner signer;

    public ArtifactDownloadController(AppService appService,
                                       ArtifactStore artifactStore,
                                       ArtifactDownloadTokenSigner signer) {
        this.appService = appService;
        this.artifactStore = artifactStore;
        this.signer = signer;
    }

    @GetMapping("/{appVersionId}")
    public ResponseEntity<InputStreamResource> download(@PathVariable UUID appVersionId,
                                                         @RequestParam("exp") long exp,
                                                         @RequestParam("sig") String sig) throws IOException {
        if (!signer.verify(appVersionId, exp, sig)) {
            return ResponseEntity.status(401).build();
        }
        Optional<AppVersion> versionOpt = appService.findVersion(appVersionId);
        if (versionOpt.isEmpty()) {
            return ResponseEntity.notFound().build();
        }
        AppVersion version = versionOpt.get();
        ArtifactCoordinates coords = appService.coordinatesFor(version);
        long size = artifactStore.size(coords);
        InputStream in = artifactStore.get(coords);
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType("application/java-archive"))
                .contentLength(size)
                .body(new InputStreamResource(in));
    }
}
