// SPDX-License-Identifier: AGPL-3.0-or-later

import * as fs from 'node:fs';
import * as path from 'node:path';
import {Readable} from 'node:stream';
import * as v8 from 'node:v8';
import {AdminACLs} from '@fluxer/constants/src/AdminACLs';
import {HeapSnapshotResponse} from '@fluxer/schema/src/domains/admin/AdminSchemas';
import {requireAdminACL} from '../../middleware/AdminMiddleware';
import {RateLimitMiddleware} from '../../middleware/RateLimitMiddleware';
import {OpenAPI} from '../../middleware/ResponseTypeMiddleware';
import {RateLimitConfigs} from '../../RateLimitConfig';
import type {HonoApp} from '../../types/HonoEnv';

export function SystemAdminController(app: HonoApp) {
	app.post(
		'/admin/system/heap-snapshot',
		RateLimitMiddleware(RateLimitConfigs.ADMIN_SYSTEM_HEAP_SNAPSHOT),
		requireAdminACL(AdminACLs.SYSTEM_HEAP_SNAPSHOT),
		OpenAPI({
			operationId: 'take_heap_snapshot',
			summary: 'Take a V8 heap snapshot',
			description:
				'Triggers a V8 heap snapshot of the current process and returns the snapshot file. Used for diagnosing memory leaks. Requires SYSTEM_HEAP_SNAPSHOT permission.',
			responseSchema: HeapSnapshotResponse,
			statusCode: 200,
			security: 'adminApiKey',
			tags: 'Admin',
		}),
		async () => {
			const snapshotPath = path.join('/tmp', `heap-${Date.now()}.heapsnapshot`);
			try {
				v8.writeHeapSnapshot(snapshotPath);
				const stat = fs.statSync(snapshotPath);
				const nodeStream = fs.createReadStream(snapshotPath);
				const body = Readable.toWeb(nodeStream) as ReadableStream;
				nodeStream.on('close', () => {
					fs.unlink(snapshotPath, () => {});
				});
				return new Response(body, {
					status: 200,
					headers: {
						'Content-Type': 'application/octet-stream',
						'Content-Disposition': `attachment; filename="${path.basename(snapshotPath)}"`,
						'Content-Length': String(stat.size),
					},
				});
			} catch (error) {
				fs.unlink(snapshotPath, () => {});
				throw error;
			}
		},
	);
}
