var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { normalizeQueryText } from "../textHash";
import { WorkspaceBackendError } from "./errors";
function normalizeFolderId(folderId) {
    if (!folderId)
        return "";
    return folderId.replace(/^\/+|\/+$/g, "");
}
function splitPath(path) {
    return path.split("/").filter(Boolean);
}
function basename(path) {
    const parts = splitPath(path);
    return parts[parts.length - 1] || "";
}
function dirname(path) {
    const parts = splitPath(path);
    parts.pop();
    return parts.join("/");
}
function nowIso() {
    return new Date().toISOString();
}
export default class InMemoryWorkspaceBackend {
    constructor(_config) {
        this._config = _config;
        this.type = "git";
        this.versionsByQueryId = new Map();
    }
    validateAccess() {
        return __awaiter(this, void 0, void 0, function* () {
            return;
        });
    }
    listFolder(folderId) {
        return __awaiter(this, void 0, void 0, function* () {
            const folder = normalizeFolderId(folderId);
            const folders = new Map();
            const queries = [];
            for (const queryId of this.versionsByQueryId.keys()) {
                const queryDir = dirname(queryId);
                if (folder === "") {
                    const top = splitPath(queryDir)[0];
                    if (top) {
                        folders.set(top, { kind: "folder", id: top, label: top, parentId: undefined });
                        continue;
                    }
                    queries.push({
                        kind: "query",
                        id: queryId,
                        label: basename(queryId).replace(/\.sparql$/i, ""),
                        parentId: undefined,
                    });
                    continue;
                }
                if (queryDir === folder) {
                    queries.push({
                        kind: "query",
                        id: queryId,
                        label: basename(queryId).replace(/\.sparql$/i, ""),
                        parentId: folder,
                    });
                    continue;
                }
                if (queryDir.startsWith(folder + "/")) {
                    const rest = queryDir.slice(folder.length + 1);
                    const child = splitPath(rest)[0];
                    if (child) {
                        const childId = folder + "/" + child;
                        folders.set(childId, { kind: "folder", id: childId, label: child, parentId: folder });
                    }
                }
            }
            const out = [...folders.values(), ...queries];
            out.sort((a, b) => a.label.localeCompare(b.label));
            return out;
        });
    }
    searchByName(query) {
        return __awaiter(this, void 0, void 0, function* () {
            const q = query.trim().toLowerCase();
            if (!q)
                return [];
            const hits = [];
            for (const queryId of this.versionsByQueryId.keys()) {
                const label = basename(queryId).replace(/\.sparql$/i, "");
                if (label.toLowerCase().includes(q)) {
                    hits.push({ kind: "query", id: queryId, label, parentId: dirname(queryId) || undefined });
                }
            }
            hits.sort((a, b) => a.label.localeCompare(b.label));
            return hits;
        });
    }
    readQuery(queryId) {
        return __awaiter(this, void 0, void 0, function* () {
            const versions = this.versionsByQueryId.get(queryId);
            if (!versions || versions.length === 0)
                throw new WorkspaceBackendError("NOT_FOUND", "Query not found");
            const latest = versions[versions.length - 1];
            return { queryText: latest.queryText, versionTag: latest.id };
        });
    }
    writeQuery(queryId, queryText, options) {
        return __awaiter(this, void 0, void 0, function* () {
            const versions = this.versionsByQueryId.get(queryId) || [];
            const latest = versions[versions.length - 1];
            if ((options === null || options === void 0 ? void 0 : options.expectedVersionTag) && latest && options.expectedVersionTag !== latest.id) {
                throw new WorkspaceBackendError("CONFLICT", "Version tag mismatch");
            }
            if (latest && normalizeQueryText(latest.queryText) === normalizeQueryText(queryText)) {
                this.versionsByQueryId.set(queryId, versions);
                return;
            }
            const nextId = `v${versions.length + 1}`;
            versions.push({ id: nextId, createdAt: nowIso(), queryText });
            this.versionsByQueryId.set(queryId, versions);
        });
    }
    listVersions(queryId) {
        return __awaiter(this, void 0, void 0, function* () {
            const versions = this.versionsByQueryId.get(queryId);
            if (!versions || versions.length === 0)
                return [];
            return [...versions]
                .slice()
                .reverse()
                .map((v) => ({ id: v.id, createdAt: v.createdAt }));
        });
    }
    readVersion(queryId, versionId) {
        return __awaiter(this, void 0, void 0, function* () {
            const versions = this.versionsByQueryId.get(queryId);
            if (!versions || versions.length === 0)
                throw new WorkspaceBackendError("NOT_FOUND", "Query not found");
            const found = versions.find((v) => v.id === versionId);
            if (!found)
                throw new WorkspaceBackendError("NOT_FOUND", "Version not found");
            return { queryText: found.queryText, versionTag: found.id };
        });
    }
    renameQuery(queryId, newLabel) {
        return __awaiter(this, void 0, void 0, function* () {
            const trimmed = newLabel.trim();
            if (!trimmed)
                throw new WorkspaceBackendError("UNKNOWN", "New name is required");
            const versions = this.versionsByQueryId.get(queryId);
            if (!versions || versions.length === 0)
                throw new WorkspaceBackendError("NOT_FOUND", "Query not found");
            const newId = dirname(queryId) ? `${dirname(queryId)}/${trimmed}.sparql` : `${trimmed}.sparql`;
            if (newId === queryId)
                return;
            if (this.versionsByQueryId.has(newId))
                throw new WorkspaceBackendError("CONFLICT", "A query with this name already exists");
            this.versionsByQueryId.delete(queryId);
            this.versionsByQueryId.set(newId, versions);
        });
    }
    deleteQuery(queryId) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.versionsByQueryId.has(queryId))
                throw new WorkspaceBackendError("NOT_FOUND", "Query not found");
            this.versionsByQueryId.delete(queryId);
        });
    }
}
//# sourceMappingURL=InMemoryWorkspaceBackend.js.map