"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 __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var ContaboProviderService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContaboProviderService = void 0;
const common_1 = require("@nestjs/common");
const config_1 = require("@nestjs/config");
const instance_entity_1 = require("../../instances/entities/instance.entity");
const instance_status_enum_1 = require("../../instances/entities/instance-status.enum");
const instance_type_enum_1 = require("../../instances/entities/instance-type.enum");
const cloud_provider_enum_1 = require("../enums/cloud-provider.enum");
const generated_1 = require("../../../modules/providers/implementations/contabo/generated");
const node_crypto_1 = require("node:crypto");
const label_service_1 = require("../../common/services/label.service");
let ContaboProviderService = ContaboProviderService_1 = class ContaboProviderService {
    constructor(configService, credentialProvider, labelService) {
        this.configService = configService;
        this.credentialProvider = credentialProvider;
        this.labelService = labelService;
        this.logger = new common_1.Logger(ContaboProviderService_1.name);
        this.FLUI_PREFIX = 'flui-';
        this.apiUrl = this.configService.get('CONTABO_API_URL', 'https://api.contabo.com');
    }
    listServersAsDto() {
        throw new common_1.NotImplementedException('Contabo provider: listServersAsDto not yet implemented');
    }
    getServerDetailsAsDto(serverId) {
        throw new common_1.NotImplementedException('Contabo provider: getServerDetailsAsDto not yet implemented');
    }
    createServer(config) {
        throw new common_1.NotImplementedException('Contabo provider: createServer not yet implemented');
    }
    deleteServer(config) {
        throw new common_1.NotImplementedException('Contabo provider: deleteServer not yet implemented');
    }
    getServerStatus(serverId) {
        throw new common_1.NotImplementedException('Contabo provider: getServerStatus not yet implemented');
    }
    testConnection() {
        throw new common_1.NotImplementedException('Contabo provider: testConnection not yet implemented');
    }
    async powerOnServer(serverId) {
        throw new common_1.NotImplementedException('Contabo provider: powerOnServer not yet implemented');
    }
    async powerOffServer(serverId) {
        throw new common_1.NotImplementedException('Contabo provider: powerOffServer not yet implemented');
    }
    async changeServerType() {
        throw new common_1.NotImplementedException('Contabo provider: changeServerType is not supported. Contabo requires re-provisioning the VPS to change its plan.');
    }
    async expandVolume() {
        throw new common_1.NotImplementedException('Contabo provider: expandVolume is not supported.');
    }
    async listInstances(filters) {
        try {
            const activeToken = await this.credentialProvider.getActiveBearerToken(cloud_provider_enum_1.CloudProvider.CONTABO);
            if (!activeToken) {
                throw new common_1.HttpException('No active token found for Contabo', common_1.HttpStatus.UNAUTHORIZED);
            }
            const configuration = new generated_1.Configuration({
                basePath: 'https://api.contabo.com',
                accessToken: activeToken.access_token,
            });
            const instancesApi = new generated_1.InstancesApi(configuration);
            const requestId = (0, node_crypto_1.randomUUID)();
            const instanceList = await instancesApi.retrieveInstancesList(requestId);
            return instanceList.data.data.map((instance) => this.mapContaboInstanceToEntity(instance));
        }
        catch (error) {
            throw new common_1.HttpException(error.message || 'Failed to list instances', error.status || common_1.HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    mapContaboInstanceToEntity(contaboInstance) {
        const instance = new instance_entity_1.InstanceEntity();
        instance.providerId = String(contaboInstance.instanceId);
        instance.name = contaboInstance.name;
        instance.displayName = contaboInstance.displayName || '';
        instance.type = instance_type_enum_1.InstanceType.VPS;
        instance.provider = cloud_provider_enum_1.CloudProvider.CONTABO;
        instance.status = this.mapContaboStatus(contaboInstance.status);
        instance.dataCenter = contaboInstance.dataCenter;
        instance.region = contaboInstance.region;
        instance.regionName = contaboInstance.regionName;
        instance.cpuCores = contaboInstance.cpuCores;
        instance.ramMb = contaboInstance.ramMb;
        instance.diskMb = contaboInstance.diskMb;
        instance.osType = contaboInstance.osType;
        instance.ipConfig = contaboInstance.ipConfig;
        instance.macAddress = contaboInstance.macAddress;
        instance.productType = contaboInstance.productType;
        instance.productName = contaboInstance.productName;
        instance.defaultUser = contaboInstance.defaultUser || '';
        instance.additionalIps =
            contaboInstance.additionalIps?.map((ip) => ip.v4.ip || '') || [];
        if (contaboInstance.createdDate) {
            instance.createdAt = new Date(contaboInstance.createdDate);
        }
        if (contaboInstance.cancelDate) {
            instance.cancelDate = new Date(contaboInstance.cancelDate);
        }
        instance.metadata = {
            vHostId: contaboInstance.vHostId,
            vHostName: contaboInstance.vHostName,
            vHostNumber: contaboInstance.vHostNumber,
            tenantId: contaboInstance.tenantId,
            imageId: contaboInstance.imageId,
            productId: contaboInstance.productId,
            errorMessage: contaboInstance.errorMessage,
            sshKeys: contaboInstance.sshKeys,
        };
        return instance;
    }
    mapContaboStatus(status) {
        switch (status?.toLowerCase()) {
            case 'running':
                return instance_status_enum_1.InstanceStatus.RUNNING;
            case 'stopped':
                return instance_status_enum_1.InstanceStatus.STOPPED;
            case 'starting':
                return instance_status_enum_1.InstanceStatus.STARTING;
            case 'stopping':
                return instance_status_enum_1.InstanceStatus.STOPPING;
            case 'provisioning':
                return instance_status_enum_1.InstanceStatus.PROVISIONING;
            case 'error':
                return instance_status_enum_1.InstanceStatus.ERROR;
            default:
                return instance_status_enum_1.InstanceStatus.UNKNOWN;
        }
    }
    async listSSHKeys() {
        return [];
    }
    async getNodeSizes() {
        throw new common_1.NotImplementedException('Contabo provider: getNodeSizes not yet implemented');
    }
    async getPricing(query) {
        throw new common_1.NotImplementedException('Contabo provider: getPricing not yet implemented');
    }
    generateSyntheticLabels(serverName) {
        if (!serverName.startsWith(this.FLUI_PREFIX)) {
            return [];
        }
        const parts = serverName.split('-');
        const labels = [{ key: 'managed-by', value: 'flui-cloud' }];
        if (parts.length > 2 && parts[1] === 'cluster') {
            labels.push({ key: 'flui-resource-type', value: 'cluster-node' });
            if (parts.length > 4) {
                const clusterName = parts[3];
                const nodeType = parts[4];
                labels.push({ key: 'flui-cluster-name', value: clusterName });
                if (nodeType === 'master' || nodeType === 'worker') {
                    labels.push({ key: 'flui-node-type', value: nodeType });
                }
            }
        }
        else {
            labels.push({ key: 'flui-resource-type', value: 'server' });
        }
        return labels;
    }
    isFluiManagedByName(serverName) {
        return serverName.startsWith(this.FLUI_PREFIX);
    }
    async createSSHKey(name, publicKey, labels) {
        throw new common_1.NotImplementedException('Contabo provider: SSH key creation not yet implemented. Configure SSH keys manually in the Contabo dashboard.');
    }
    async deleteSSHKey(providerKeyId) {
        this.logger.warn(`Contabo provider: SSH key deletion not implemented. Key ${providerKeyId} must be deleted manually from the Contabo dashboard.`);
    }
    async getSSHKey(providerKeyId) {
        throw new common_1.NotImplementedException(`Contabo provider: SSH key retrieval not yet implemented. Key ${providerKeyId} details not available.`);
    }
    async updateServerLabels(serverId, labels) {
        this.logger.warn(`Contabo provider: label updates not supported. Server ${serverId} labels cannot be updated via API.`);
    }
};
exports.ContaboProviderService = ContaboProviderService;
exports.ContaboProviderService = ContaboProviderService = ContaboProviderService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(1, (0, common_1.Inject)('ICredentialProvider')),
    __metadata("design:paramtypes", [config_1.ConfigService, Object, label_service_1.LabelService])
], ContaboProviderService);
