import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { z } from "zod";
import type { RepoConfig } from "@/types/index.js";

const repoEntrySchema = z.object({
  name: z.string().min(1),
  url: z
    .string()
    .regex(
      /^(?:https?:\/\/|git@)github\.com[/:][\w.-]+\/[\w.-]+(?:\.git)?$/,
      "Must be a valid GitHub HTTPS or SSH URL",
    ),
  description: z.string().min(1),
  keywords: z.array(z.string()).min(1),
  contextFiles: z.array(z.string()).optional(),
  defaultBranch: z.string().optional(),
  rulesFile: z.string().optional(),
  rulesIndexFile: z.string().optional(),
  subtaskPrefix: z.string().optional(),
  prTitleTemplate: z.string().optional(),
  prLabels: z
    .object({
      bugfix: z.array(z.string()).optional(),
      hotfix: z.array(z.string()).optional(),
      default: z.array(z.string()).optional(),
    })
    .optional(),
  checkScripts: z.array(z.string()).optional(),
  remoteRulesRepo: z.string().optional(),
});

const reposFileSchema = z.object({
  repos: z.array(repoEntrySchema).min(1),
});

export class RepoRegistry {
  private readonly repos: RepoConfig[];

  constructor(configPath?: string) {
    const filePath = configPath ?? resolve(process.cwd(), "repos.json");
    const raw = readFileSync(filePath, "utf-8");
    const parsed = reposFileSchema.parse(JSON.parse(raw));
    this.repos = parsed.repos;
  }

  getAll(): readonly RepoConfig[] {
    return this.repos;
  }

  getByName(name: string): RepoConfig | undefined {
    return this.repos.find((r) => r.name === name);
  }
}
