import { readFile } from 'node:fs/promises';

export const FACTORY_WORKFLOW = 'factory-kubernetes';

export interface RepositoryRecord {
  id: string;
  canonical_url: string;
  github: { owner: string; repository: string };
  credential: { handle: string; profile: string };
  allowed_workflows: string[];
  resource_policy: Record<string, string>;
  network_policy: { profile: string; allowed_hosts: string[] };
  result_publication: { result_ref_prefix: string; retain_on_failure: boolean };
}

interface RegistryDocument {
  version: 1;
  repositories: RepositoryRecord[];
}

export async function loadRepositoryRegistry(path: string): Promise<RegistryDocument> {
  const raw = JSON.parse(await readFile(path, 'utf8')) as RegistryDocument;
  if (raw.version !== 1 || !Array.isArray(raw.repositories)) {
    throw new Error('Repository registry has unsupported schema');
  }
  const ids = new Set<string>();
  for (const repository of raw.repositories) {
    if (!/^[a-z0-9][a-z0-9-]{0,62}$/.test(repository.id) || ids.has(repository.id)) {
      throw new Error('Repository registry IDs must be unique stable identifiers');
    }
    ids.add(repository.id);
    if (repository.canonical_url !== `https://github.com/${repository.github.owner}/${repository.github.repository}.git`) {
      throw new Error('Repository canonical URL and GitHub identity disagree');
    }
  }
  return raw;
}

export function resolveRepository(registry: RegistryDocument, repositoryId: string, workflow: string): RepositoryRecord {
  const repository = registry.repositories.find((item) => item.id === repositoryId);
  if (!repository) throw new Error('Repository ID is not registered');
  if (!repository.allowed_workflows.includes(workflow)) throw new Error('Workflow is not authorized for repository');
  return repository;
}
