import fs from 'fs';
import path from 'path';
import { createRequire } from 'module';

const requireHere = createRequire(__filename);

function uniquePaths(paths: Array<string | undefined | null>): string[] {
  const seen = new Set<string>();
  const out: string[] = [];

  for (const candidate of paths) {
    if (typeof candidate !== 'string') continue;
    const trimmed = candidate.trim();
    if (!trimmed || seen.has(trimmed)) continue;
    seen.add(trimmed);
    out.push(trimmed);
  }

  return out;
}

function buildTokenMappingLoaderCandidates(): string[] {
  return uniquePaths([
    process.env.TOKEN_MAPPING_LOADER_PATH,
    process.env.GRU_TRANSPORT_LOADER_PATH,
    process.env.PROXMOX_TOKEN_MAPPING_LOADER_PATH,
    path.resolve(process.cwd(), 'config', 'token-mapping-loader.cjs'),
    path.resolve(process.cwd(), '..', 'config', 'token-mapping-loader.cjs'),
    path.resolve(process.cwd(), '..', '..', 'config', 'token-mapping-loader.cjs'),
    path.resolve(process.cwd(), '..', '..', '..', 'config', 'token-mapping-loader.cjs'),
    path.resolve(__dirname, '../../../../../config/token-mapping-loader.cjs'),
  ]);
}

export function resolveTokenMappingLoaderPath(): string | null {
  for (const candidate of buildTokenMappingLoaderCandidates()) {
    if (fs.existsSync(candidate)) {
      return candidate;
    }
  }
  return null;
}

export function loadTokenMappingLoader<T>(): T | null {
  const loaderPath = resolveTokenMappingLoaderPath();
  if (!loaderPath) return null;

  try {
    return requireHere(loaderPath) as T;
  } catch {
    return null;
  }
}
