import electron from 'electron';
import { readFile } from 'node:fs/promises';
import { join, normalize, sep, extname } from 'node:path';

const { protocol } = electron;

export function registerSchemesAsPrivileged(): void {
  protocol.registerSchemesAsPrivileged([
    { scheme: 'inkling-media', privileges: { secure: true, supportFetchAPI: true, stream: true } }
  ]);
}

export function inferMime(filename: string): string {
  const ext = extname(filename).toLowerCase();
  switch (ext) {
    case '.png': return 'image/png';
    case '.jpg':
    case '.jpeg': return 'image/jpeg';
    case '.gif': return 'image/gif';
    case '.webp': return 'image/webp';
    default: return 'application/octet-stream';
  }
}

export function registerInklingMediaProtocol(profileDir: string): void {
  const mediaRoot = join(profileDir, 'media');
  protocol.handle('inkling-media', async (req) => {
    // Raw URL 에서 `..` 세그먼트 (URL-encoded 포함) 검출 — `new URL()` 이 normalize 하기 전에 차단.
    const rawLower = req.url.toLowerCase();
    if (
      rawLower.includes('/../') ||
      rawLower.endsWith('/..') ||
      rawLower.includes('/%2e%2e/') ||
      rawLower.endsWith('/%2e%2e')
    ) {
      return new Response(null, { status: 403 });
    }
    const url = new URL(req.url);
    // inkling-media://media/<noteId>/<file> → host='media', pathname='/<noteId>/<file>'
    const relPath = decodeURIComponent(`${url.host}${url.pathname}`);
    const target = normalize(join(profileDir, relPath));
    if (!target.startsWith(mediaRoot + sep) && target !== mediaRoot) {
      return new Response(null, { status: 403 });
    }
    try {
      const data = await readFile(target);
      return new Response(new Uint8Array(data), {
        headers: { 'content-type': inferMime(target) }
      });
    } catch {
      return new Response(null, { status: 404 });
    }
  });
}
