"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.CAController = 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 ca_manager_service_1 = require("../services/ca-manager.service");
const certificate_signer_service_1 = require("../services/certificate-signer.service");
const ca_public_key_dto_1 = require("../dto/ca-public-key.dto");
const register_ca_dto_1 = require("../dto/register-ca.dto");
let CAController = class CAController {
    constructor(caManager, certificateSigner) {
        this.caManager = caManager;
        this.certificateSigner = certificateSigner;
    }
    async initializeCA() {
        const ca = await this.caManager.initializeCA();
        return {
            publicKey: ca.publicKey,
            fingerprint: ca.fingerprint,
            type: ca.type,
            createdAt: ca.createdAt,
            expiresAt: ca.expiresAt,
        };
    }
    async registerCA(dto) {
        const ca = await this.caManager.registerExternalCA(dto.publicKey, {
            name: dto.name,
            replace: dto.replace,
            metadata: dto.metadata,
        });
        return {
            id: ca.id,
            name: ca.name,
            publicKey: ca.publicKey,
            fingerprint: ca.fingerprint,
            type: ca.type,
            createdAt: ca.createdAt,
            expiresAt: ca.expiresAt,
            message: dto.replace
                ? 'CA replaced successfully'
                : 'CA registered successfully',
        };
    }
    async getCAInfo() {
        const ca = await this.caManager.getCAInfo();
        return {
            publicKey: ca.publicKey,
            fingerprint: ca.fingerprint,
            type: ca.type,
            createdAt: ca.createdAt,
            expiresAt: ca.expiresAt,
        };
    }
    async getEnrollmentScript() {
        const script = await this.caManager.getEnrollmentScript();
        return { script };
    }
    async generateTestCertificate(ttl = 180) {
        const ttlSeconds = ttl;
        const cert = await this.certificateSigner.generateEphemeralCertificate('test', ttlSeconds);
        const expiresAt = new Date(Date.now() + ttlSeconds * 1000);
        return {
            privateKey: cert.privateKey,
            certificate: cert.certificate,
            expiresAt: expiresAt.toISOString(),
            principals: ['root', 'ubuntu', 'admin'],
            instructions: `
# How to use this certificate for SSH testing on Windows:

# 1. Save the private key and certificate to files:
echo "${cert.privateKey.replaceAll('n', '\n')}" > ephemeral_key
echo "${cert.certificate.replaceAll('n', '\n')}" > ephemeral_key-cert.pub

# 2. Set correct permissions (Git Bash):
chmod 600 ephemeral_key
chmod 644 ephemeral_key-cert.pub

# 3. Connect to your server:
ssh -i ephemeral_key root@YOUR_SERVER_IP

# Certificate expires at: ${expiresAt.toISOString()}
# Valid for principals: root, ubuntu, admin
# TTL: ${ttlSeconds} seconds (${Math.floor(ttlSeconds / 60)} minutes)

# Note: The certificate file MUST be named <keyfile>-cert.pub
# SSH automatically looks for the certificate file when you specify the key.
      `.trim(),
        };
    }
};
exports.CAController = CAController;
__decorate([
    (0, common_1.Post)('initialize'),
    (0, common_1.UseGuards)(admin_guard_1.AdminGuard),
    (0, admin_decorator_1.Admin)(),
    (0, common_1.HttpCode)(common_1.HttpStatus.CREATED),
    (0, swagger_1.ApiOperation)({ summary: 'Initialize CA keypair (admin only)' }),
    (0, swagger_1.ApiResponse)({
        status: 201,
        description: 'CA initialized successfully',
        type: ca_public_key_dto_1.CAPublicKeyDto,
    }),
    (0, swagger_1.ApiResponse)({
        status: 409,
        description: 'CA already exists',
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], CAController.prototype, "initializeCA", null);
__decorate([
    (0, common_1.Post)('register'),
    (0, common_1.HttpCode)(common_1.HttpStatus.CREATED),
    (0, swagger_1.ApiOperation)({
        summary: 'Register external CA public key from CLI',
        description: 'Registers an external CA public key (generated by CLI). Only stores the public key, no private key is transmitted or stored.',
    }),
    (0, swagger_1.ApiResponse)({
        status: 201,
        description: 'CA registered successfully',
        type: register_ca_dto_1.RegisterCAResponseDto,
    }),
    (0, swagger_1.ApiResponse)({
        status: 400,
        description: 'Invalid public key format',
    }),
    (0, swagger_1.ApiResponse)({
        status: 409,
        description: 'CA already exists',
    }),
    __param(0, (0, common_1.Body)()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [register_ca_dto_1.RegisterCADto]),
    __metadata("design:returntype", Promise)
], CAController.prototype, "registerCA", null);
__decorate([
    (0, common_1.Get)('info'),
    (0, swagger_1.ApiOperation)({ summary: 'Get CA info (without private key)' }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'CA info retrieved',
        type: ca_public_key_dto_1.CAPublicKeyDto,
    }),
    (0, swagger_1.ApiResponse)({
        status: 404,
        description: 'No active CA found',
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], CAController.prototype, "getCAInfo", null);
__decorate([
    (0, common_1.Get)('enrollment-script'),
    (0, swagger_1.ApiOperation)({ summary: 'Get server enrollment script' }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'Enrollment script generated successfully',
        schema: {
            type: 'object',
            properties: {
                script: {
                    type: 'string',
                    description: 'Bash script for server enrollment',
                },
            },
        },
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise)
], CAController.prototype, "getEnrollmentScript", null);
__decorate([
    (0, common_1.Post)('test-certificate'),
    (0, common_1.HttpCode)(common_1.HttpStatus.OK),
    (0, swagger_1.ApiOperation)({
        summary: 'Generate ephemeral certificate for testing (DEV ONLY)',
        description: 'Generates an ephemeral certificate for manual SSH testing. Returns private key and certificate that can be used with ssh command line.',
    }),
    (0, swagger_1.ApiQuery)({
        name: 'ttl',
        required: false,
        type: Number,
        description: 'Certificate TTL in seconds (default: 180)',
        example: 180,
    }),
    (0, swagger_1.ApiResponse)({
        status: 200,
        description: 'Certificate generated successfully',
        schema: {
            type: 'object',
            properties: {
                privateKey: {
                    type: 'string',
                    description: 'ED25519 private key (PEM format)',
                },
                certificate: {
                    type: 'string',
                    description: 'SSH certificate signed by CA',
                },
                expiresAt: {
                    type: 'string',
                    format: 'date-time',
                    description: 'Certificate expiration time',
                },
                principals: {
                    type: 'array',
                    items: { type: 'string' },
                    description: 'Valid principals (usernames)',
                },
                instructions: {
                    type: 'string',
                    description: 'Command line usage instructions',
                },
            },
        },
    }),
    __param(0, (0, common_1.Query)('ttl')),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], CAController.prototype, "generateTestCertificate", null);
exports.CAController = CAController = __decorate([
    (0, swagger_1.ApiTags)('CA Management'),
    (0, swagger_1.ApiBearerAuth)(),
    (0, common_1.Controller)('access/ca'),
    __metadata("design:paramtypes", [ca_manager_service_1.CAManagerService,
        certificate_signer_service_1.CertificateSignerService])
], CAController);
