"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 HetznerObjectStorageConnectionService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.HetznerObjectStorageConnectionService = void 0;
const common_1 = require("@nestjs/common");
const api_token_repository_1 = require("../../../../access/repositories/api-token.repository");
const credentials_entity_1 = require("../../../../management/entities/credentials.entity");
const cloud_provider_enum_1 = require("../../../enums/cloud-provider.enum");
const credential_purpose_enum_1 = require("../../../../access/enums/credential-purpose.enum");
const key_storage_service_1 = require("../../../../access/services/key-storage.service");
const generic_s3_backend_1 = require("../../../../storage/implementations/generic-s3.backend");
const storage_backend_provider_enum_1 = require("../../../../storage/enums/storage-backend-provider.enum");
const DEFAULT_REGION = 'nbg1';
function endpointFor(region) {
    return `https://${region}.your-objectstorage.com`;
}
let HetznerObjectStorageConnectionService = HetznerObjectStorageConnectionService_1 = class HetznerObjectStorageConnectionService {
    constructor(apiTokenRepo, keyStorage, genericS3) {
        this.apiTokenRepo = apiTokenRepo;
        this.keyStorage = keyStorage;
        this.genericS3 = genericS3;
        this.logger = new common_1.Logger(HetznerObjectStorageConnectionService_1.name);
    }
    async connect(input) {
        const region = input.region ?? DEFAULT_REGION;
        const endpoint = endpointFor(region);
        const probeBucket = `flui-probe-${Date.now().toString(36)}`;
        // Validate creds via probe bucket create+delete
        try {
            await this.genericS3.ensureBucket({
                provider: storage_backend_provider_enum_1.StorageBackendProvider.HETZNER_OBJECT_STORAGE,
                endpoint,
                region,
                bucket: probeBucket,
                accessKey: input.accessKey,
                secretKey: input.secretKey,
                forcePathStyle: true,
            });
        }
        catch (err) {
            throw new common_1.BadRequestException(`Hetzner Object Storage credentials invalid: ${err?.message ?? err}`);
        }
        // Best-effort cleanup of probe bucket
        try {
            await this.genericS3.deleteObjects({
                provider: storage_backend_provider_enum_1.StorageBackendProvider.HETZNER_OBJECT_STORAGE,
                endpoint,
                region,
                bucket: probeBucket,
                accessKey: input.accessKey,
                secretKey: input.secretKey,
                forcePathStyle: true,
            }, []);
        }
        catch {
            // ignore — we couldn't enumerate, but the key is valid
        }
        // Disable previous OS credentials for Hetzner (only one active per user assumed for MVP)
        const existing = await this.apiTokenRepo.findByProviderAndPurpose(cloud_provider_enum_1.CloudProvider.HETZNER, credential_purpose_enum_1.CredentialPurpose.OBJECT_STORAGE);
        for (const t of existing ?? []) {
            try {
                await this.apiTokenRepo.deleteToken(t.id);
            }
            catch (err) {
                this.logger.warn(`Failed to delete previous Hetzner OS token ${t.id}: ${err?.message}`);
            }
        }
        const encryptedSecret = this.keyStorage.encryptKeyToString(input.secretKey);
        const encryptedAccess = this.keyStorage.encryptKeyToString(input.accessKey);
        const created = await this.apiTokenRepo.createToken(cloud_provider_enum_1.CloudProvider.HETZNER, `Hetzner Object Storage (${region})`, `Auto-saved by Flui at ${new Date().toISOString()}`, encryptedSecret, {
            credentialType: credentials_entity_1.CredentialType.ACCESS_KEY_SECRET,
            encryptedAccessKey: encryptedAccess,
            purpose: credential_purpose_enum_1.CredentialPurpose.OBJECT_STORAGE,
        });
        return { ready: true, tokenId: created.id };
    }
    async loadCreds() {
        const tokens = await this.apiTokenRepo.findByProviderAndPurpose(cloud_provider_enum_1.CloudProvider.HETZNER, credential_purpose_enum_1.CredentialPurpose.OBJECT_STORAGE);
        const t = tokens?.[0];
        if (!t)
            return null;
        const secretKey = this.keyStorage.decryptKeyFromString(t.encrypted_token);
        const accessKey = t.encrypted_access_key
            ? this.keyStorage.decryptKeyFromString(t.encrypted_access_key)
            : '';
        // Region inferred from label "(nbg1)"
        const match = t.label ? /\((\w+)\)/.exec(t.label) : null;
        const region = match?.[1] ?? DEFAULT_REGION;
        return { accessKey, secretKey, region };
    }
};
exports.HetznerObjectStorageConnectionService = HetznerObjectStorageConnectionService;
exports.HetznerObjectStorageConnectionService = HetznerObjectStorageConnectionService = HetznerObjectStorageConnectionService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [api_token_repository_1.ApiTokenRepository,
        key_storage_service_1.KeyStorageService,
        generic_s3_backend_1.GenericS3Backend])
], HetznerObjectStorageConnectionService);
