"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); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccessController = void 0;
const common_1 = require("@nestjs/common");
const swagger_1 = require("@nestjs/swagger");
const admin_guard_1 = require("../auth/guards/admin.guard");
const admin_decorator_1 = require("../auth/decorators/admin.decorator");
const access_service_1 = require("./services/access.service");
const create_ssh_key_dto_1 = require("./dto/create-ssh-key.dto");
const bearer_token_dto_1 = require("./dto/bearer-token.dto");
const create_bearer_token_dto_1 = require("./dto/create-bearer-token.dto");
const refresh_token_dto_1 = require("./dto/refresh-token.dto");
const create_api_token_dto_1 = require("./dto/create-api-token.dto");
const api_token_dto_1 = require("./dto/api-token.dto");
const ssh_key_dto_1 = require("./dto/ssh-key.dto");
const update_ssh_key_dto_1 = require("./dto/update-ssh-key.dto");
const cloud_provider_enum_1 = require("../providers/enums/cloud-provider.enum");
let AccessController = class AccessController {
    constructor(accessService) {
        this.accessService = accessService;
    }
    async listSSHKeys(provider, clusterId, clusterNodeId, autoGenerated) {
        // Build tag filters object
        const tagFilters = {};
        if (clusterId) {
            // Support both single values and comma-separated multiple values
            if (clusterId.includes(',')) {
                tagFilters['cluster-id'] = clusterId.split(',').map((id) => id.trim());
            }
            else {
                tagFilters['cluster-id'] = clusterId;
            }
        }
        if (clusterNodeId) {
            tagFilters['cluster-node-id'] = clusterNodeId;
        }
        if (autoGenerated === 'true') {
            tagFilters['auto-generated'] = 'true';
        }
        return this.accessService.listSSHKeys(provider, tagFilters);
    }
    async addSSHKey(req, createSSHKeyDto, res) {
        const result = await this.accessService.addSSHKey(createSSHKeyDto);
        if (result.syncErrors && Object.keys(result.syncErrors).length > 0) {
            res.status(common_1.HttpStatus.MULTI_STATUS);
        }
        else {
            res.status(common_1.HttpStatus.CREATED);
        }
        return result;
    }
    async updateSSHKey(id, updateSSHKeyDto, res) {
        const result = await this.accessService.updateSSHKey(id, updateSSHKeyDto);
        if (result.syncErrors && Object.keys(result.syncErrors).length > 0) {
            res.status(common_1.HttpStatus.MULTI_STATUS);
        }
        return result;
    }
    async removeSSHKey(req, id, removeFromProviders, provider) {
        const shouldRemoveFromProviders = removeFromProviders !== 'false';
        return this.accessService.removeSSHKey('', id, shouldRemoveFromProviders, provider);
    }
    async generateBearerToken(createBearerTokenDto) {
        return this.accessService.generateBearerToken(createBearerTokenDto.provider, createBearerTokenDto);
    }
    async refreshToken(dto) {
        return this.accessService.refreshBearerToken(dto.provider, dto);
    }
    async listBearerTokens() {
        return await this.accessService.listBearerTokens();
    }
    async removeBearerToken(id) {
        return await this.accessService.removeBearerToken(id);
    }
    async listApiTokens() {
        return await this.accessService.listApiTokens();
    }
    async createApiToken(createApiTokenDto) {
        return await this.accessService.createApiToken(createApiTokenDto);
    }
    async getApiToken(id) {
        return await this.accessService.getApiToken(id);
    }
    async removeApiToken(id) {
        return await this.accessService.removeApiToken(id);
    }
};
exports.AccessController = AccessController;
__decorate([
    (0, common_1.Get)('ssh-keys'),
    (0, swagger_1.ApiOperation)({
        summary: 'List SSH keys',
        description: 'Returns SSH keys from local database and optionally from cloud provider. Can filter by tags like cluster-id and cluster_node_id. Supports array values for filtering multiple clusters.',
    }),
    (0, swagger_1.ApiQuery)({
        name: 'provider',
        enum: cloud_provider_enum_1.CloudProvider,
        required: false,
        description: 'Include SSH keys from specific cloud provider',
    }),
    (0, swagger_1.ApiQuery)({
        name: 'cluster-id',
        required: false,
        description: 'Filter SSH keys by cluster ID tag. Can be a single value or comma-separated list',
        example: 'k3s-prod-eu-001,k3s-prod-eu-002',
    }),
    (0, swagger_1.ApiQuery)({
        name: 'cluster-node-id',
        required: false,
        description: 'Filter SSH keys by cluster node ID tag',
        example: 'node-master-01',
    }),
    (0, swagger_1.ApiQuery)({
        name: 'auto-generated',
        required: false,
        description: 'Filter by auto-generated keys only (keys automatically created by the system)',
        example: 'true',
    }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'Returns all SSH keys from database and provider',
        type: [ssh_key_dto_1.SSHKeyDto],
    }),
    __param(0, (0, common_1.Query)('provider')),
    __param(1, (0, common_1.Query)('cluster-id')),
    __param(2, (0, common_1.Query)('cluster-node-id')),
    __param(3, (0, common_1.Query)('auto-generated')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, String, String]),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "listSSHKeys", null);
__decorate([
    (0, common_1.Post)('ssh-keys'),
    (0, swagger_1.ApiOperation)({ summary: 'Add SSH key' }),
    (0, swagger_1.ApiResponse)({
        status: 201,
        description: 'SSH key created and synced to all providers successfully',
        type: ssh_key_dto_1.SSHKeyDto,
    }),
    (0, swagger_1.ApiResponse)({
        status: 207,
        description: 'SSH key created but one or more provider syncs failed. Check syncErrors in response body.',
        type: ssh_key_dto_1.SSHKeyDto,
    }),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Res)({ passthrough: true })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, create_ssh_key_dto_1.CreateSSHKeyDto, Object]),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "addSSHKey", null);
__decorate([
    (0, common_1.Patch)('ssh-keys/:id'),
    (0, swagger_1.ApiOperation)({
        summary: 'Update SSH key',
        description: 'Update SSH key tags, providerKeyMappings, or trigger sync to additional providers via syncProviders. ' +
            'Tags are completely replaced, not merged.',
    }),
    (0, swagger_1.ApiParam)({
        name: 'id',
        description: 'SSH key ID',
        type: 'string',
        example: '123e4567-e89b-12d3-a456-426614174000',
    }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'SSH key updated successfully',
        type: ssh_key_dto_1.SSHKeyDto,
    }),
    (0, swagger_1.ApiResponse)({
        status: 207,
        description: 'Update applied but one or more provider syncs failed. Check syncErrors in response body.',
        type: ssh_key_dto_1.SSHKeyDto,
    }),
    (0, swagger_1.ApiResponse)({ status: 404, description: 'SSH key not found' }),
    __param(0, (0, common_1.Param)('id')),
    __param(1, (0, common_1.Body)()),
    __param(2, (0, common_1.Res)({ passthrough: true })),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, update_ssh_key_dto_1.UpdateSSHKeyDto, Object]),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "updateSSHKey", null);
__decorate([
    (0, common_1.Delete)('ssh-keys/:id'),
    (0, common_1.UseGuards)(admin_guard_1.AdminGuard),
    (0, admin_decorator_1.Admin)(),
    (0, swagger_1.ApiOperation)({
        summary: 'Remove SSH key',
        description: 'Deletes the SSH key from the local database. ' +
            'By default also removes it from all synced cloud providers. ' +
            'Set removeFromProviders=false to delete only locally.',
    }),
    (0, swagger_1.ApiQuery)({
        name: 'removeFromProviders',
        required: false,
        type: Boolean,
        description: 'Also remove from synced cloud providers (default: true)',
    }),
    (0, swagger_1.ApiQuery)({
        name: 'provider',
        required: false,
        enum: cloud_provider_enum_1.CloudProvider,
        description: 'Required when deleting a key that exists only on the provider (not in DB)',
    }),
    (0, swagger_1.ApiResponse)({ status: 200, description: 'SSH key removed successfully' }),
    __param(0, (0, common_1.Request)()),
    __param(1, (0, common_1.Param)('id')),
    __param(2, (0, common_1.Query)('removeFromProviders')),
    __param(3, (0, common_1.Query)('provider')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, String, String, String]),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "removeSSHKey", null);
__decorate([
    (0, common_1.Post)('bearer'),
    (0, swagger_1.ApiOperation)({ summary: 'Generate bearer token for cloud provider' }),
    (0, swagger_1.ApiResponse)({
        status: 201,
        description: 'Bearer token generated successfully',
        type: bearer_token_dto_1.BearerTokenDto,
    }),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [create_bearer_token_dto_1.CreateBearerTokenDto]),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "generateBearerToken", null);
__decorate([
    (0, common_1.Post)('bearer/refresh'),
    (0, swagger_1.ApiOperation)({ summary: 'Refresh bearer token' }),
    (0, common_1.HttpCode)(common_1.HttpStatus.OK),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'Bearer token refreshed successfully',
        type: bearer_token_dto_1.BearerTokenDto,
    }),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [refresh_token_dto_1.ProviderRefreshTokenDto]),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "refreshToken", null);
__decorate([
    (0, common_1.Get)('bearer'),
    (0, swagger_1.ApiOperation)({ summary: 'List all bearer tokens' }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'Returns all bearer tokens',
        type: [bearer_token_dto_1.BearerTokenDto],
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "listBearerTokens", null);
__decorate([
    (0, common_1.Delete)('bearer/:id'),
    (0, common_1.UseGuards)(admin_guard_1.AdminGuard),
    (0, admin_decorator_1.Admin)(),
    (0, swagger_1.ApiOperation)({ summary: 'Remove bearer token' }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'Bearer token removed successfully',
    }),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "removeBearerToken", null);
__decorate([
    (0, common_1.Get)('api-tokens'),
    (0, swagger_1.ApiOperation)({ summary: 'List all stored API tokens' }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'Returns all stored API tokens',
        type: [api_token_dto_1.ApiTokenDto],
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "listApiTokens", null);
__decorate([
    (0, common_1.Post)('api-tokens'),
    (0, swagger_1.ApiOperation)({ summary: 'Store API token from external provider' }),
    (0, swagger_1.ApiResponse)({
        status: 201,
        description: 'API token stored successfully',
        type: api_token_dto_1.ApiTokenDto,
    }),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [create_api_token_dto_1.CreateApiTokenDto]),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "createApiToken", null);
__decorate([
    (0, common_1.Get)('api-tokens/:id'),
    (0, swagger_1.ApiOperation)({ summary: 'Get API token information by ID' }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'Returns the API token information without the token value',
        type: api_token_dto_1.ApiTokenDto,
    }),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "getApiToken", null);
__decorate([
    (0, common_1.Delete)('api-tokens/:id'),
    (0, common_1.UseGuards)(admin_guard_1.AdminGuard),
    (0, admin_decorator_1.Admin)(),
    (0, swagger_1.ApiOperation)({ summary: 'Remove stored API token' }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'API token removed successfully',
    }),
    __param(0, (0, common_1.Param)('id')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String]),
    __metadata("design:returntype", Promise)
], AccessController.prototype, "removeApiToken", null);
exports.AccessController = AccessController = __decorate([
    (0, swagger_1.ApiTags)('Access Management'),
    (0, swagger_1.ApiBearerAuth)(),
    (0, common_1.Controller)('access'),
    __metadata("design:paramtypes", [access_service_1.AccessService])
], AccessController);
