package com.cameleer.server.core.runtime;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.UUID;

public class DeploymentService {
    private static final Logger log = LoggerFactory.getLogger(DeploymentService.class);

    private final DeploymentRepository deployRepo;
    private final AppService appService;
    private final EnvironmentService envService;

    public DeploymentService(DeploymentRepository deployRepo, AppService appService, EnvironmentService envService) {
        this.deployRepo = deployRepo;
        this.appService = appService;
        this.envService = envService;
    }

    public List<Deployment> listByApp(UUID appId) { return deployRepo.findByAppId(appId); }
    public Deployment getById(UUID id) { return deployRepo.findById(id).orElseThrow(() -> new IllegalArgumentException("Deployment not found: " + id)); }

    /** Create a deployment record. Actual container start is handled by DeploymentExecutor (async). */
    public Deployment createDeployment(UUID appId, UUID appVersionId, UUID environmentId, String createdBy) {
        App app = appService.getById(appId);
        Environment env = envService.getById(environmentId);
        String containerName = env.slug() + "-" + app.slug();

        deployRepo.deleteFailedByAppAndEnvironment(appId, environmentId);
        UUID deploymentId = deployRepo.create(appId, appVersionId, environmentId, containerName, createdBy);
        return deployRepo.findById(deploymentId).orElseThrow();
    }

    /** Promote: deploy the same app version to a different environment. */
    public Deployment promote(UUID appId, UUID appVersionId, UUID targetEnvironmentId, String createdBy) {
        return createDeployment(appId, appVersionId, targetEnvironmentId, createdBy);
    }

    public void markRunning(UUID deploymentId, String containerId) {
        deployRepo.updateStatus(deploymentId, DeploymentStatus.RUNNING, containerId, null);
        deployRepo.markDeployed(deploymentId);
    }

    public void markFailed(UUID deploymentId, String errorMessage) {
        deployRepo.updateStatus(deploymentId, DeploymentStatus.FAILED, null, errorMessage);
    }

    public void markStopped(UUID deploymentId) {
        deployRepo.updateStatus(deploymentId, DeploymentStatus.STOPPED, null, null);
        deployRepo.markStopped(deploymentId);
    }
}
