"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProviderSyncService = exports.CredentialType = exports.CloudProvider = void 0;
const api_client_1 = require("../api-client");
const config_storage_1 = require("../config-storage");
/**
 * Provider sync service - Synchronizes CLI provider configuration to API
 */
// Enums matching API
var CloudProvider;
(function (CloudProvider) {
    CloudProvider["HETZNER"] = "hetzner";
    CloudProvider["SCALEWAY"] = "scaleway";
})(CloudProvider || (exports.CloudProvider = CloudProvider = {}));
var CredentialType;
(function (CredentialType) {
    CredentialType["API_KEY"] = "api_key";
    CredentialType["ACCESS_KEY_SECRET"] = "access_key_secret";
    CredentialType["USER_PASSWORD"] = "user_password";
    CredentialType["BEARER_TOKEN"] = "bearer_token";
})(CredentialType || (exports.CredentialType = CredentialType = {}));
// Provider-specific region configurations
const PROVIDER_REGIONS = {
    [CloudProvider.HETZNER]: ['nbg1', 'fsn1', 'hel1', 'ash', 'hil'],
    [CloudProvider.SCALEWAY]: ['fr-par', 'nl-ams', 'pl-waw'],
};
class ProviderSyncService {
    constructor(apiUrl) {
        this.configStorage = new config_storage_1.ConfigStorage();
        this.apiClient = new api_client_1.ApiClient({
            baseUrl: apiUrl,
            apiKey: this.configStorage.getApiKey(),
        });
    }
    setApiKey(apiKey) {
        this.apiClient = new api_client_1.ApiClient({
            baseUrl: this.apiClient.getBaseUrl(),
            apiKey,
        });
    }
    /**
     * Check if provider exists in API
     */
    async checkProviderExists(provider) {
        try {
            await this.apiClient.get(`/management/configurations/${provider}`);
            return true;
        }
        catch (error) {
            if (error.statusCode === 404) {
                return false;
            }
            throw error;
        }
    }
    /**
     * Get provider configuration from API
     */
    async getProviderConfiguration(provider) {
        try {
            const config = await this.apiClient.get(`/management/configurations/${provider}`);
            return config;
        }
        catch (error) {
            if (error.statusCode === 404) {
                return null;
            }
            throw error;
        }
    }
    /**
     * Validate provider is supported
     */
    validateProvider(provider) {
        const normalizedProvider = provider.toLowerCase();
        if (!Object.values(CloudProvider).includes(normalizedProvider)) {
            throw new Error(`Unsupported provider: ${provider}. Supported providers: ${Object.values(CloudProvider).join(', ')}`);
        }
        return normalizedProvider;
    }
    /**
     * Get credential type for provider
     */
    getCredentialType(provider) {
        if (provider === CloudProvider.SCALEWAY) {
            return CredentialType.ACCESS_KEY_SECRET;
        }
        return CredentialType.API_KEY;
    }
    /**
     * Get regions to enable for provider
     */
    getRegionsToEnable(provider, specifiedRegions) {
        if (specifiedRegions && specifiedRegions.length > 0) {
            return specifiedRegions;
        }
        // Return all available regions for provider
        return PROVIDER_REGIONS[provider] || [];
    }
    /**
     * Build ConfigureProviderDto from CLI config
     */
    async buildConfigureDto(provider, regions) {
        const credentialType = this.getCredentialType(provider);
        const enabledRegions = this.getRegionsToEnable(provider, regions);
        const credentials = {
            provider,
            type: credentialType,
        };
        if (credentialType === CredentialType.ACCESS_KEY_SECRET) {
            const stored = this.configStorage.getCredentials(provider);
            if (!stored?.accessKey || !stored?.secretKey) {
                throw new Error(`No credentials found for ${provider}. Configure them with: flui config set ${provider}`);
            }
            credentials.accessKey = stored.accessKey;
            credentials.secretKey = stored.secretKey;
        }
        else {
            const apiToken = this.configStorage.getToken(provider);
            if (!apiToken) {
                throw new Error(`No API token found for ${provider}. Please configure it first using: flui config set ${provider} <token>`);
            }
            if (credentialType === CredentialType.API_KEY) {
                credentials.apiKey = apiToken;
            }
            else if (credentialType === CredentialType.BEARER_TOKEN) {
                credentials.bearerToken = apiToken;
            }
        }
        return {
            provider,
            credentials,
            enabledRegions,
            additionalConfig: {},
        };
    }
    /**
     * Sync provider from CLI to API
     */
    async syncProvider(providerName, options = {}) {
        try {
            // Validate provider
            const provider = this.validateProvider(providerName);
            // Check if provider already exists
            const existingConfig = await this.getProviderConfiguration(provider);
            if (existingConfig && !options.force) {
                return {
                    success: false,
                    message: `Provider ${provider} is already configured in the API. Use --force to overwrite.`,
                    providerConfiguration: existingConfig,
                };
            }
            // Build configuration DTO
            const configDto = await this.buildConfigureDto(provider, options.regions);
            // Configure provider in API
            const response = await this.apiClient.post(`/management/providers/${provider}/configure`, configDto);
            return {
                success: true,
                message: `Successfully synced ${provider} provider to API`,
                providerConfiguration: response,
            };
        }
        catch (error) {
            return {
                success: false,
                message: `Failed to sync provider: ${error.message}`,
                error: error.details || error.message,
            };
        }
    }
    /**
     * Get API client base URL
     */
    getApiUrl() {
        return this.apiClient.getBaseUrl();
    }
}
exports.ProviderSyncService = ProviderSyncService;
