package net.siegeln.cameleer.saas.vendor;

import net.siegeln.cameleer.saas.provisioning.ServerStatus;
import net.siegeln.cameleer.saas.tenant.TenantEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/api/vendor/metrics")
@PreAuthorize("hasAuthority('SCOPE_platform:admin')")
public class TenantMetricsController {

    private final VendorTenantService vendorTenantService;
    private final TenantMetricsService metricsService;

    public TenantMetricsController(VendorTenantService vendorTenantService,
                                   TenantMetricsService metricsService) {
        this.vendorTenantService = vendorTenantService;
        this.metricsService = metricsService;
    }

    public record TenantMetricsEntry(
            String tenantId,
            String tenantName,
            String slug,
            String tier,
            String status,
            String serverState,
            TenantMetricsService.MetricsSummary metrics
    ) {}

    @GetMapping
    public ResponseEntity<List<TenantMetricsEntry>> all() {
        List<TenantEntity> tenants = vendorTenantService.listAll();

        List<CompletableFuture<TenantMetricsEntry>> futures = tenants.stream()
                .map(tenant -> CompletableFuture.supplyAsync(() -> {
                    ServerStatus serverStatus = vendorTenantService.getServerStatus(tenant);
                    String state = serverStatus.state().name();

                    TenantMetricsService.MetricsSummary metrics = null;
                    String endpoint = tenant.getServerEndpoint();
                    boolean isRunning = "ACTIVE".equals(tenant.getStatus().name())
                            && endpoint != null && !endpoint.isBlank()
                            && "RUNNING".equals(state);
                    if (isRunning) {
                        metrics = metricsService.getMetricsSummary(endpoint);
                    }

                    return new TenantMetricsEntry(
                            tenant.getId().toString(),
                            tenant.getName(),
                            tenant.getSlug(),
                            tenant.getTier().name(),
                            tenant.getStatus().name(),
                            state,
                            metrics
                    );
                }))
                .toList();

        List<TenantMetricsEntry> entries = futures.stream()
                .map(CompletableFuture::join)
                .toList();

        return ResponseEntity.ok(entries);
    }
}
