import path from 'path';

import { DATA_DIR, GROUPS_DIR } from './config.js';

const GROUP_FOLDER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/;
const RUNTIME_SEGMENT_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
const RESERVED_FOLDERS = new Set(['global']);

export function isValidGroupFolder(folder: string): boolean {
  if (!folder) return false;
  if (folder !== folder.trim()) return false;
  if (!GROUP_FOLDER_PATTERN.test(folder)) return false;
  if (folder.includes('/') || folder.includes('\\')) return false;
  if (folder.includes('..')) return false;
  if (RESERVED_FOLDERS.has(folder.toLowerCase())) return false;
  return true;
}

export function assertValidGroupFolder(folder: string): void {
  if (!isValidGroupFolder(folder)) {
    throw new Error(`Invalid group folder "${folder}"`);
  }
}

function assertValidRuntimeSegment(segment: string, label: string): void {
  if (!segment || segment !== segment.trim()) {
    throw new Error(`Invalid ${label} "${segment}"`);
  }
  if (!RUNTIME_SEGMENT_PATTERN.test(segment)) {
    throw new Error(`Invalid ${label} "${segment}"`);
  }
  if (
    segment.includes('/') ||
    segment.includes('\\') ||
    segment.includes('..')
  ) {
    throw new Error(`Invalid ${label} "${segment}"`);
  }
}

function ensureWithinBase(baseDir: string, resolvedPath: string): void {
  const rel = path.relative(baseDir, resolvedPath);
  if (rel.startsWith('..') || path.isAbsolute(rel)) {
    throw new Error(`Path escapes base directory: ${resolvedPath}`);
  }
}

export function resolveGroupFolderPath(folder: string): string {
  assertValidGroupFolder(folder);
  const groupPath = path.resolve(GROUPS_DIR, folder);
  ensureWithinBase(GROUPS_DIR, groupPath);
  return groupPath;
}

export function resolveGroupIpcPath(folder: string): string {
  assertValidGroupFolder(folder);
  const ipcBaseDir = path.resolve(DATA_DIR, 'ipc');
  const ipcPath = path.resolve(ipcBaseDir, folder);
  ensureWithinBase(ipcBaseDir, ipcPath);
  return ipcPath;
}

export function resolveGroupSessionsPath(folder: string): string {
  assertValidGroupFolder(folder);
  const sessionsBaseDir = path.resolve(DATA_DIR, 'sessions');
  const sessionsPath = path.resolve(sessionsBaseDir, folder);
  ensureWithinBase(sessionsBaseDir, sessionsPath);
  return sessionsPath;
}

export function resolveServiceGroupSessionsPath(
  folder: string,
  serviceId: string,
): string {
  assertValidGroupFolder(folder);
  assertValidRuntimeSegment(serviceId, 'service ID');
  const sessionsBaseDir = path.resolve(DATA_DIR, 'sessions');
  const sessionsPath = path.resolve(
    sessionsBaseDir,
    folder,
    'services',
    serviceId,
  );
  ensureWithinBase(sessionsBaseDir, sessionsPath);
  return sessionsPath;
}

export function resolveTaskRuntimeIpcPath(
  folder: string,
  taskId: string,
): string {
  assertValidGroupFolder(folder);
  assertValidRuntimeSegment(taskId, 'task ID');
  const ipcBaseDir = path.resolve(DATA_DIR, 'ipc');
  const ipcPath = path.resolve(ipcBaseDir, folder, 'tasks', taskId);
  ensureWithinBase(ipcBaseDir, ipcPath);
  return ipcPath;
}

export function resolveTaskSessionsPath(
  folder: string,
  taskId: string,
): string {
  assertValidGroupFolder(folder);
  assertValidRuntimeSegment(taskId, 'task ID');
  const sessionsBaseDir = path.resolve(DATA_DIR, 'sessions');
  const sessionsPath = path.resolve(sessionsBaseDir, folder, 'tasks', taskId);
  ensureWithinBase(sessionsBaseDir, sessionsPath);
  return sessionsPath;
}

export function resolveServiceTaskSessionsPath(
  folder: string,
  serviceId: string,
  taskId: string,
): string {
  assertValidGroupFolder(folder);
  assertValidRuntimeSegment(serviceId, 'service ID');
  assertValidRuntimeSegment(taskId, 'task ID');
  const sessionsBaseDir = path.resolve(DATA_DIR, 'sessions');
  const sessionsPath = path.resolve(
    sessionsBaseDir,
    folder,
    'services',
    serviceId,
    'tasks',
    taskId,
  );
  ensureWithinBase(sessionsBaseDir, sessionsPath);
  return sessionsPath;
}

export function resolvePairedTaskWorkspaceRoot(
  folder: string,
  taskId: string,
): string {
  assertValidGroupFolder(folder);
  assertValidRuntimeSegment(taskId, 'task ID');
  const workspacesBaseDir = path.resolve(DATA_DIR, 'workspaces');
  const workspacesPath = path.resolve(
    workspacesBaseDir,
    folder,
    'tasks',
    taskId,
  );
  ensureWithinBase(workspacesBaseDir, workspacesPath);
  return workspacesPath;
}

export function resolvePairedTaskWorkspacePath(
  folder: string,
  taskId: string,
  role: 'owner' | 'reviewer',
): string {
  assertValidRuntimeSegment(role, 'workspace role');
  const workspaceRoot = resolvePairedTaskWorkspaceRoot(folder, taskId);
  const workspacePath = path.resolve(workspaceRoot, role);
  ensureWithinBase(workspaceRoot, workspacePath);
  return workspacePath;
}
