/**
 * Types for the GitHub repository crawler (TRUEREF-0003).
 */

import type { TrueRefConfig } from '$lib/types';

// Re-export RepoConfig alias so crawler modules can reference it consistently.
export type RepoConfig = TrueRefConfig;

// ---------------------------------------------------------------------------
// Core crawler data types
// ---------------------------------------------------------------------------

export interface CrawledFile {
	/** Relative path within the repo, e.g. "src/index.ts" */
	path: string;
	/** UTF-8 file content */
	content: string;
	/** File size in bytes */
	size: number;
	/** GitHub blob SHA (used as checksum) */
	sha: string;
	/** Programming language detected from extension */
	language: string;
}

export interface CrawlResult {
	/** Successfully downloaded files */
	files: CrawledFile[];
	/** Total files that matched filters */
	totalFiles: number;
	/** Files that were filtered out or too large */
	skippedFiles: number;
	/** Branch or tag that was crawled */
	branch: string;
	/** HEAD commit SHA */
	commitSha: string;
}

export interface CrawlOptions {
	owner: string;
	repo: string;
	/** Branch, tag, or commit SHA; defaults to repo default branch */
	ref?: string;
	/** GitHub PAT for private repos */
	token?: string;
	/** Parsed trueref.json / context7.json configuration */
	config?: RepoConfig;
	/** Progress callback invoked after each file is processed */
	onProgress?: (processed: number, total: number) => void;
}

// ---------------------------------------------------------------------------
// GitHub API response shapes (minimal — only fields we use)
// ---------------------------------------------------------------------------

export interface GitHubRepoResponse {
	default_branch: string;
	stargazers_count: number;
}

export interface GitHubTreeItem {
	path: string;
	type: 'blob' | 'tree';
	size?: number;
	sha: string;
	url: string;
}

export interface GitHubTreeResponse {
	tree: GitHubTreeItem[];
	truncated: boolean;
}

export interface GitHubContentResponse {
	content: string;
	encoding: string;
	size: number;
	sha: string;
}

// ---------------------------------------------------------------------------
// Domain errors
// ---------------------------------------------------------------------------

export class RepositoryNotFoundError extends Error {
	readonly code = 'REPOSITORY_NOT_FOUND';
	constructor(message: string) {
		super(message);
		this.name = 'RepositoryNotFoundError';
	}
}

export class AuthenticationError extends Error {
	readonly code = 'AUTHENTICATION_ERROR';
	constructor(message: string) {
		super(message);
		this.name = 'AuthenticationError';
	}
}

export class PermissionError extends Error {
	readonly code = 'PERMISSION_ERROR';
	constructor(message: string) {
		super(message);
		this.name = 'PermissionError';
	}
}

export class RateLimitError extends Error {
	readonly code = 'RATE_LIMIT_ERROR';
	constructor(
		message: string,
		public readonly resetAt: number
	) {
		super(message);
		this.name = 'RateLimitError';
	}
}

export class NotAGitRepositoryError extends Error {
	readonly code = 'NOT_A_GIT_REPOSITORY';
	constructor(message: string) {
		super(message);
		this.name = 'NotAGitRepositoryError';
	}
}

export class InvalidRefError extends Error {
	readonly code = 'INVALID_REF';
	constructor(message: string) {
		super(message);
		this.name = 'InvalidRefError';
	}
}
