"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var ScalewayObjectStorageProvisioner_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScalewayObjectStorageProvisioner = void 0;
const common_1 = require("@nestjs/common");
const object_storage_provisioner_interface_1 = require("../../../../storage/interfaces/object-storage-provisioner.interface");
const storage_backend_provider_enum_1 = require("../../../../storage/enums/storage-backend-provider.enum");
const api_token_repository_1 = require("../../../../access/repositories/api-token.repository");
const credential_purpose_enum_1 = require("../../../../access/enums/credential-purpose.enum");
const credentials_entity_1 = require("../../../../management/entities/credentials.entity");
const cloud_provider_enum_1 = require("../../../enums/cloud-provider.enum");
const key_storage_service_1 = require("../../../../access/services/key-storage.service");
const generic_s3_backend_1 = require("../../../../storage/implementations/generic-s3.backend");
const SCALEWAY_DEFAULT_REGION = 'fr-par';
function endpointFor(region) {
    return `https://s3.${region}.scw.cloud`;
}
/**
 * Provisioner Scaleway Object Storage — FULL_AUTO.
 * Riusa le credenziali Scaleway compute esistenti (Scaleway IAM access keys
 * unificati: la stessa key opera su Compute API e Object Storage S3 API).
 *
 * Future: estendere ScalewayIamAdapter con createApplicationKey scoped al
 * bucket per least-privilege per-destination.
 */
let ScalewayObjectStorageProvisioner = ScalewayObjectStorageProvisioner_1 = class ScalewayObjectStorageProvisioner {
    constructor(apiTokenRepo, keyStorage, genericS3) {
        this.apiTokenRepo = apiTokenRepo;
        this.keyStorage = keyStorage;
        this.genericS3 = genericS3;
        this.logger = new common_1.Logger(ScalewayObjectStorageProvisioner_1.name);
        this.provider = storage_backend_provider_enum_1.StorageBackendProvider.SCALEWAY_OBJECT_STORAGE;
        this.capability = object_storage_provisioner_interface_1.ProvisionerCapability.FULL_AUTO;
    }
    async isReady(_userId) {
        const tokens = await this.apiTokenRepo.findByProviderAndPurpose(cloud_provider_enum_1.CloudProvider.SCALEWAY, credential_purpose_enum_1.CredentialPurpose.COMPUTE);
        const hasAccessKey = tokens?.some((t) => t.credential_type === credentials_entity_1.CredentialType.ACCESS_KEY_SECRET);
        if (!hasAccessKey) {
            return {
                ready: false,
                reason: 'CONNECT_SCALEWAY_REQUIRED',
                message: 'Scaleway non collegato. Aggiungi credenziali Scaleway nelle impostazioni provider.',
            };
        }
        return { ready: true };
    }
    async provisionDestination(input) {
        const region = input.desiredRegion ?? SCALEWAY_DEFAULT_REGION;
        const endpoint = endpointFor(region);
        const bucket = input.desiredBucketName ?? this.defaultBucketName(input.userId);
        const { accessKey, secretKey } = await this.loadScalewayCreds();
        const alreadyExisted = await this.bucketExists(endpoint, region, bucket, accessKey, secretKey);
        if (!alreadyExisted) {
            await this.genericS3.ensureBucket({
                provider: this.provider,
                endpoint,
                region,
                bucket,
                accessKey,
                secretKey,
                forcePathStyle: false,
            });
        }
        return {
            bucket,
            region,
            endpoint,
            forcePathStyle: false,
            pathPrefix: `flui/${input.clusterId}`,
            accessKey,
            secretKey,
            // Costi calcolati dal BillingEstimatorService (per-provider table) in cents-per-TB.
            usableForEtcdL1: true,
            alreadyExisted,
        };
    }
    defaultBucketName(userId) {
        const short = userId.replaceAll('-', '').slice(0, 12).toLowerCase();
        return `flui-backups-${short}`;
    }
    async loadScalewayCreds() {
        const tokens = await this.apiTokenRepo.findByProviderAndPurpose(cloud_provider_enum_1.CloudProvider.SCALEWAY, credential_purpose_enum_1.CredentialPurpose.COMPUTE);
        const t = tokens?.find((x) => x.credential_type === credentials_entity_1.CredentialType.ACCESS_KEY_SECRET);
        if (!t)
            throw new Error('Scaleway access key not found');
        const secretKey = this.keyStorage.decryptKeyFromString(t.encrypted_token);
        const accessKey = t.encrypted_access_key
            ? this.keyStorage.decryptKeyFromString(t.encrypted_access_key)
            : '';
        return { accessKey, secretKey };
    }
    async bucketExists(endpoint, region, bucket, accessKey, secretKey) {
        const result = await this.genericS3.testConnection({
            provider: this.provider,
            endpoint,
            region,
            bucket,
            accessKey,
            secretKey,
            forcePathStyle: false,
        });
        return result.healthy;
    }
};
exports.ScalewayObjectStorageProvisioner = ScalewayObjectStorageProvisioner;
exports.ScalewayObjectStorageProvisioner = ScalewayObjectStorageProvisioner = ScalewayObjectStorageProvisioner_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [api_token_repository_1.ApiTokenRepository,
        key_storage_service_1.KeyStorageService,
        generic_s3_backend_1.GenericS3Backend])
], ScalewayObjectStorageProvisioner);
