"use client";
import { useCallback } from "react";
import { base64ToBytes, normalizeGitHubContent } from "./decodeGitHubContent.js";
import { parseGitUrl } from "./parseGitUrl.js";
const GITHUB_API = "https://api.github.com/repos";
/**
 * Upper bound on files we will pull through the Blob API (Gate 1, Option B).
 *
 * The Contents API caps at ~1 MB and signals larger files with
 * `encoding: "none"`; the Blob API then serves them in full (up to GitHub's own
 * ~100 MB blob limit). Since we only ever display the first ~1 MB, downloading
 * a 90 MB blob to show 1 MB is wasteful — so above this ceiling we report the
 * file as too-large
 * (`text: null`, `truncated: true`) using the size GitHub already told us,
 * without downloading anything.
 */
const BLOB_FETCH_CEILING_BYTES = 10 * 1024 * 1024; // 10 MiB
/** Encode a repo-relative path per segment, preserving the slashes. */
function encodePath(path) {
    return path.split("/").map(encodeURIComponent).join("/");
}
/**
 * Creates a {@link WorkspaceFileReader} backed by the GitHub Contents API,
 * with a Blob-API fallback for files above the Contents 1 MB cap.
 *
 * Uses the same client-side OAuth token as {@link useGitHubTreeLister}
 * (`Authorization: Bearer`), inheriting its private-repo scope. Returns
 * `undefined` when no token is present, mirroring the tree lister so callers
 * can treat "no reader" and "no lister" identically.
 *
 * The reader itself:
 * - Returns `null` when the entry is not a readable GitHub git repo
 *   (non-git entry, missing/unparseable URL) — the "unsupported here" state.
 * - **Throws** on a real failure: a non-OK response, or a directory path
 *   (which the Contents API returns as a JSON array). Consumers surface these
 *   as an error, distinct from the null "unsupported" state.
 *
 * @example
 * ```tsx
 * const gitHubConnection = useGitHubConnection(org);
 * const fileReader = useGitHubFileReader(gitHubConnection.token);
 * <SessionViewer workspaceFileReader={fileReader} />
 * ```
 */
export function useGitHubFileReader(token) {
    const reader = useCallback(async (entry, path) => {
        if (entry.type !== "git" || !entry.gitUrl || !token)
            return null;
        const parsed = parseGitUrl(entry.gitUrl);
        if (!parsed)
            return null;
        const branch = entry.gitBranch || "main";
        const url = `${GITHUB_API}/${parsed.owner}/${parsed.repo}/contents/${encodePath(path)}` +
            `?ref=${encodeURIComponent(branch)}`;
        const resp = await fetch(url, {
            headers: { Authorization: `Bearer ${token}` },
        });
        if (!resp.ok) {
            throw new Error(`GitHub content fetch failed for ${path} (HTTP ${resp.status})`);
        }
        const data = await resp.json();
        // The Contents API returns an array for a directory — a misdirected read,
        // not an unsupported substrate, so fail loudly rather than return null.
        if (Array.isArray(data)) {
            throw new Error(`Cannot read "${path}": path is a directory`);
        }
        const file = data;
        if (file.encoding === "base64") {
            return normalizeGitHubContent(base64ToBytes(file.content), file.size);
        }
        // encoding: "none" is GitHub's signal that the file exceeds the Contents
        // API's ~1 MB cap; the bytes live only behind the Blob API.
        return readViaBlob(parsed, file, token);
    }, [token]);
    if (!token)
        return undefined;
    return reader;
}
/**
 * Gate 1 / Option B — size-gated blob fetch for files the Contents API refused
 * (`encoding: "none"`). Isolated so the large-file policy can change without
 * touching the reader's control flow.
 */
async function readViaBlob(parsed, file, token) {
    // Above the ceiling we never download — GitHub already told us the size, so
    // report it as too-large-to-preview without spending the bandwidth.
    if (file.size > BLOB_FETCH_CEILING_BYTES) {
        return {
            text: null,
            isBinary: false,
            size: file.size,
            encoding: "none",
            truncated: true,
        };
    }
    const url = `${GITHUB_API}/${parsed.owner}/${parsed.repo}/git/blobs/${file.sha}`;
    const resp = await fetch(url, {
        headers: { Authorization: `Bearer ${token}` },
    });
    if (!resp.ok) {
        throw new Error(`GitHub blob fetch failed for ${file.sha} (HTTP ${resp.status})`);
    }
    const blob = await resp.json();
    return normalizeGitHubContent(base64ToBytes(blob.content), blob.size);
}
//# sourceMappingURL=useGitHubFileReader.js.map