"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerNginxServerRoutes = registerNginxServerRoutes;
const errors_1 = require("@yinuo-ngm/errors");
const nginx_route_context_1 = require("./nginx-route.context");
function registerNginxServerRoutes(context) {
    const { fastify, nginx } = context;
    const buildRuntimeStatus = (enabled, nginxRunning, pendingReload) => {
        if (!enabled) {
            return 'disabled';
        }
        if (nginxRunning === null) {
            return 'unknown';
        }
        if (pendingReload) {
            return 'pending';
        }
        return nginxRunning ? 'running' : 'stopped';
    };
    const parseIsoMs = (value) => {
        const text = String(value || '').trim();
        if (!text) {
            return null;
        }
        const ms = Date.parse(text);
        return Number.isFinite(ms) ? ms : null;
    };
    const isServerPendingReload = (server, nginxRunning, lastAppliedAt) => {
        if (!server.enabled || !nginxRunning) {
            return false;
        }
        if (lastAppliedAt === null) {
            return false;
        }
        const changedAt = parseIsoMs(server.updatedAt) ?? parseIsoMs(server.createdAt);
        if (changedAt === null) {
            return false;
        }
        return changedAt > lastAppliedAt;
    };
    const resolveActor = (request) => {
        const directHeader = request.headers['x-ngm-user'] || request.headers['x-user'] || request.headers['x-username'];
        if (typeof directHeader === 'string' && directHeader.trim()) {
            return directHeader.trim();
        }
        const user = request?.user;
        if (typeof user?.name === 'string' && user.name.trim()) {
            return user.name.trim();
        }
        if (typeof user?.username === 'string' && user.username.trim()) {
            return user.username.trim();
        }
        if (typeof user?.id === 'string' && user.id.trim()) {
            return user.id.trim();
        }
        return undefined;
    };
    fastify.get('/servers', async (_request, reply) => {
        try {
            const servers = await nginx.server.getAllServers();
            let nginxRunning = null;
            let lastAppliedAt = null;
            try {
                const status = await nginx.service.getStatus();
                nginxRunning = Boolean(status.isRunning);
                lastAppliedAt = nginx.service.getLastConfigAppliedAt();
            }
            catch {
                nginxRunning = null;
            }
            const enriched = servers.map(server => ({
                ...server,
                runtimeStatus: buildRuntimeStatus(Boolean(server.enabled), nginxRunning, isServerPendingReload(server, nginxRunning, lastAppliedAt)),
            }));
            return reply.send({
                success: true,
                servers: enriched,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
    fastify.get('/servers/:id', async (request, reply) => {
        const { id } = request.params;
        try {
            const server = await nginx.server.getServer(id);
            if (!server) {
                throw new errors_1.GlobalError(errors_1.GlobalErrorCodes.NOT_FOUND, 'Server 不存在');
            }
            let nginxRunning = null;
            let lastAppliedAt = null;
            try {
                const status = await nginx.service.getStatus();
                nginxRunning = Boolean(status.isRunning);
                lastAppliedAt = nginx.service.getLastConfigAppliedAt();
            }
            catch {
                nginxRunning = null;
            }
            const enriched = {
                ...server,
                runtimeStatus: buildRuntimeStatus(Boolean(server.enabled), nginxRunning, isServerPendingReload(server, nginxRunning, lastAppliedAt)),
            };
            return reply.send({
                success: true,
                server: enriched,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
    fastify.post('/servers', async (request, reply) => {
        try {
            const actor = resolveActor(request);
            const payload = actor
                ? { ...request.body, createdBy: request.body?.createdBy || actor }
                : { ...request.body };
            const server = await nginx.server.createServer(payload);
            return reply.send({
                success: true,
                server,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
    fastify.put('/servers/:id', async (request, reply) => {
        const { id } = request.params;
        try {
            const server = await nginx.server.updateServer(id, request.body);
            return reply.send({
                success: true,
                server,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
    fastify.delete('/servers/:id', async (request, reply) => {
        const { id } = request.params;
        try {
            const result = await nginx.server.deleteServer(id);
            return reply.send({
                success: true,
                snapshotId: result.snapshotId,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
    fastify.post('/servers/restore-deleted', async (request, reply) => {
        try {
            const snapshotId = String(request.body?.snapshotId || '').trim();
            if (!snapshotId) {
                throw new errors_1.GlobalError(errors_1.GlobalErrorCodes.BAD_REQUEST, 'snapshotId 不能为空');
            }
            const server = await nginx.server.restoreDeletedServer(snapshotId);
            return reply.send({
                success: true,
                server,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
    fastify.patch('/servers/:id/enable', async (request, reply) => {
        const { id } = request.params;
        try {
            await nginx.server.enableServer(id);
            return reply.send({
                success: true,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
    fastify.patch('/servers/:id/disable', async (request, reply) => {
        const { id } = request.params;
        try {
            await nginx.server.disableServer(id);
            return reply.send({
                success: true,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
    fastify.post('/servers/import/parse', async (request, reply) => {
        try {
            const content = String(request.body?.content || '').trim();
            if (!content) {
                return reply.send({
                    success: true,
                    candidates: [],
                });
            }
            const candidates = await nginx.server.parseImportCandidates(content);
            return reply.send({
                success: true,
                candidates,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
    fastify.post('/servers/import/analyze', async (request, reply) => {
        try {
            const requests = Array.isArray(request.body?.requests) ? request.body.requests : [];
            const candidates = await nginx.server.analyzeImportRequests(requests);
            return reply.send({
                success: true,
                candidates,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
    fastify.post('/servers/validate-ssl-paths', async (request, reply) => {
        try {
            const certPath = String(request.body?.sslCert || '').trim();
            const keyPath = String(request.body?.sslKey || '').trim();
            const cert = certPath
                ? await nginx.service.validateFileReadable(certPath)
                : { exists: false, readable: false, error: '证书路径为空' };
            const key = keyPath
                ? await nginx.service.validateFileReadable(keyPath)
                : { exists: false, readable: false, error: '私钥路径为空' };
            return reply.send({
                success: true,
                valid: cert.exists && cert.readable && key.exists && key.readable,
                cert,
                key,
            });
        }
        catch (error) {
            return (0, nginx_route_context_1.sendBadRequest)(reply, error);
        }
    });
}
