"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fastify_1 = __importDefault(require("fastify"));
const cors_1 = __importDefault(require("@fastify/cors"));
const multipart_1 = __importDefault(require("@fastify/multipart"));
const env_1 = require("./config/env");
const logger_1 = require("./utils/logger");
const videos_routes_1 = require("./modules/media/routes/videos.routes");
const video_streaming_routes_1 = require("./modules/media/routes/video-streaming.routes");
const reactions_routes_1 = require("./modules/media/routes/reactions.routes");
const public_routes_1 = require("./modules/media/routes/public.routes");
const chat_stream_routes_1 = require("./modules/media/routes/chat-stream.routes");
const comments_routes_1 = require("./modules/media/routes/comments.routes");
const upload_routes_1 = require("./modules/media/routes/upload.routes");
const video_actions_routes_1 = require("./modules/media/routes/video-actions.routes");
const video_schedule_routes_1 = require("./modules/media/routes/video-schedule.routes");
const video_tracking_routes_1 = require("./modules/media/routes/video-tracking.routes");
const comment_admin_routes_1 = require("./modules/media/routes/comment-admin.routes");
const chat_notifications_routes_1 = require("./modules/media/routes/chat-notifications.routes");
const chat_threads_routes_1 = require("./modules/media/routes/chat-threads.routes");
const user_profile_routes_1 = require("./modules/media/routes/user-profile.routes");
const shorts_routes_1 = require("./modules/media/routes/shorts.routes");
const upvote_routes_1 = require("./modules/media/routes/upvote.routes");
const video_schedule_queue_service_1 = require("./services/video-schedule-queue.service");
const video_fetch_queue_service_1 = require("./services/video-fetch-queue.service");
const fetch_routes_1 = require("./modules/media/routes/fetch.routes");
const playlists_public_routes_1 = require("./modules/media/routes/playlists-public.routes");
const playlists_user_routes_1 = require("./modules/media/routes/playlists-user.routes");
const playlists_admin_routes_1 = require("./modules/media/routes/playlists-admin.routes");
const photos_routes_1 = require("./modules/media/routes/photos.routes");
const photo_upload_routes_1 = require("./modules/media/routes/photo-upload.routes");
const photo_albums_routes_1 = require("./modules/media/routes/photo-albums.routes");
const photos_public_routes_1 = require("./modules/media/routes/photos-public.routes");
const photo_engagement_routes_1 = require("./modules/media/routes/photo-engagement.routes");
// Add BigInt serialization support for Prisma BigInt fields
// This converts BigInt values to strings when JSON.stringify() is called
BigInt.prototype.toJSON = function () {
    return this.toString();
};
const fastify = (0, fastify_1.default)({
    logger: {
        level: env_1.env.NODE_ENV === 'production' ? 'info' : 'debug',
    },
    maxParamLength: 500,
    trustProxy: true,
});
// Graceful shutdown handler
process.on('SIGTERM', async () => {
    logger_1.logger.info('SIGTERM received, shutting down gracefully...');
    await video_schedule_queue_service_1.videoScheduleQueueService.close();
    await video_fetch_queue_service_1.videoFetchQueueService.close();
    fastify.close(() => {
        logger_1.logger.info('Media API server closed');
        process.exit(0);
    });
});
// Global error handlers
process.on('unhandledRejection', (reason, promise) => {
    logger_1.logger.error('Unhandled Promise Rejection in Media API', { reason: JSON.stringify(reason), promise: JSON.stringify(promise) });
});
process.on('uncaughtException', (error) => {
    logger_1.logger.error('Uncaught Exception in Media API', { error: error instanceof Error ? error.message : JSON.stringify(error) });
    fastify.close(() => {
        process.exit(1);
    });
});
// Start server
const start = async () => {
    try {
        // CORS configuration — allow admin app + MkDocs docs site
        const allowedOrigins = env_1.env.CORS_ORIGINS.split(',').map(o => o.trim());
        // Auto-add MkDocs origins so video cards/players work in docs
        const mkdocsOrigin = `http://localhost:${env_1.env.MKDOCS_PORT || 4003}`;
        if (!allowedOrigins.includes(mkdocsOrigin)) {
            allowedOrigins.push(mkdocsOrigin);
        }
        // Also allow the docs subdomain in production (docs.domain.org)
        for (const origin of [...allowedOrigins]) {
            const match = origin.match(/^(https?:\/\/)app\./);
            if (match) {
                const docsOrigin = origin.replace(/^(https?:\/\/)app\./, '$1docs.');
                if (!allowedOrigins.includes(docsOrigin)) {
                    allowedOrigins.push(docsOrigin);
                }
            }
        }
        await fastify.register(cors_1.default, {
            origin: (origin, cb) => {
                // Allow requests with no origin (mobile apps, curl, etc.)
                if (!origin) {
                    cb(null, true);
                    return;
                }
                // Check if origin is in allowed list
                if (allowedOrigins.includes(origin)) {
                    cb(null, true);
                }
                else {
                    cb(new Error('CORS not allowed'), false);
                }
            },
            credentials: true,
        });
        // Multipart support for file uploads (10GB limit)
        await fastify.register(multipart_1.default, {
            limits: {
                fileSize: env_1.env.MAX_UPLOAD_SIZE_GB * 1024 * 1024 * 1024,
            },
        });
        // Health check
        fastify.get('/health', async () => {
            return {
                status: 'ok',
                timestamp: new Date().toISOString(),
                service: 'media-api'
            };
        });
        // Register routes
        await fastify.register(videos_routes_1.videosRoutes, { prefix: '/api/videos' });
        await fastify.register(video_streaming_routes_1.videoStreamingRoutes, { prefix: '/api/videos' });
        await fastify.register(upload_routes_1.uploadRoutes, { prefix: '/api/videos' });
        await fastify.register(video_actions_routes_1.videoActionsRoutes, { prefix: '/api/videos' });
        await fastify.register(video_schedule_routes_1.videoScheduleRoutes, { prefix: '/api/videos' });
        await fastify.register(video_tracking_routes_1.videoTrackingRoutes, { prefix: '/api/track' });
        await fastify.register(reactions_routes_1.reactionsRoutes, { prefix: '/api/reactions' });
        await fastify.register(public_routes_1.publicRoutes, { prefix: '/api' });
        await fastify.register(comments_routes_1.commentsRoutes, { prefix: '/api' });
        await fastify.register(chat_stream_routes_1.chatStreamRoutes, { prefix: '/api' });
        await fastify.register(comment_admin_routes_1.commentAdminRoutes, { prefix: '/api/media' });
        await fastify.register(chat_notifications_routes_1.chatNotificationsRoutes, { prefix: '/api/media' });
        await fastify.register(chat_threads_routes_1.chatThreadsRoutes, { prefix: '/api/media' });
        await fastify.register(user_profile_routes_1.userProfileRoutes, { prefix: '/api/media' });
        await fastify.register(fetch_routes_1.fetchRoutes, { prefix: '/api/videos' });
        await fastify.register(shorts_routes_1.shortsRoutes, { prefix: '/api' });
        await fastify.register(upvote_routes_1.upvoteRoutes, { prefix: '/api' });
        await fastify.register(playlists_public_routes_1.playlistsPublicRoutes, { prefix: '/api/playlists' });
        await fastify.register(playlists_user_routes_1.playlistsUserRoutes, { prefix: '/api/playlists' });
        await fastify.register(playlists_admin_routes_1.playlistsAdminRoutes, { prefix: '/api/media' });
        // Photo gallery routes
        await fastify.register(photos_routes_1.photosRoutes, { prefix: '/api/photos' });
        await fastify.register(photo_upload_routes_1.photoUploadRoutes, { prefix: '/api/photos' });
        await fastify.register(photo_albums_routes_1.photoAlbumsRoutes, { prefix: '/api/albums' });
        await fastify.register(photos_public_routes_1.photosPublicRoutes, { prefix: '/api' });
        await fastify.register(photo_engagement_routes_1.photoEngagementRoutes, { prefix: '/api' });
        // 404 handler for unmatched routes
        fastify.setNotFoundHandler((_request, reply) => {
            reply.status(404).send({ error: { message: 'Route not found', code: 'NOT_FOUND' } });
        });
        const port = env_1.env.MEDIA_API_PORT;
        const host = '0.0.0.0';
        await fastify.listen({ port, host });
        logger_1.logger.info(`Media API listening on http://${host}:${port}`);
        // Start video schedule queue worker
        video_schedule_queue_service_1.videoScheduleQueueService.startWorker();
        logger_1.logger.info('Video schedule queue worker initialized');
        // Start video fetch queue worker
        video_fetch_queue_service_1.videoFetchQueueService.startWorker();
        logger_1.logger.info('Video fetch queue worker initialized');
        if (env_1.env.ENABLE_MEDIA_FEATURES !== 'true') {
            logger_1.logger.warn('Media features are disabled (ENABLE_MEDIA_FEATURES=false)');
        }
    }
    catch (err) {
        logger_1.logger.error('Media API startup error', { error: err instanceof Error ? err.message : JSON.stringify(err) });
        process.exit(1);
    }
};
start();
//# sourceMappingURL=media-server.js.map