import type { Resource, ResourceMeta } from '../types.ts';

export class ResourceConflictError extends Error {
  constructor() {
    super('A resource with that hash is already registered');
  }
}

export class ResourceNotFoundError extends Error {
  constructor(id: number) {
    super(`No resource found with id ${id}`);
  }
}

export class ResourceRegistry {
  private readonly byId = new Map<number, Resource>();
  private readonly hashes = new Set<string>();

  register(resource: Omit<Resource, 'id'>): number {
    if (this.hashes.has(resource.hash)) throw new ResourceConflictError();

    let id = 0;
    while (this.byId.has(id)) id++;

    const full: Resource = { ...resource, id };
    this.byId.set(id, full);
    this.hashes.add(resource.hash);
    return id;
  }

  get(id: number): Resource {
    const r = this.byId.get(id);
    if (!r) throw new ResourceNotFoundError(id);
    return r;
  }

  getAll(): Record<number, ResourceMeta> {
    const out: Record<number, ResourceMeta> = {};
    for (const [id, r] of this.byId) {
      const { fetch: _fetch, ...meta } = r;
      out[id] = meta;
    }
    return out;
  }

  updateRange(id: number, startsAt: number, endsAt: number): void {
    const r = this.byId.get(id);
    if (!r) throw new ResourceNotFoundError(id);
    r.startsAt = startsAt;
    r.endsAt = endsAt;
  }
}
