import { useActiveEntities } from "../../../store/active-entities.js";
import { specDictionary } from "../../../store/import-spec.js";
import { useWorkspace } from "../../../store/store.js";
import { combineRenameDiffs, mutateCollectionDiff, mutateRequestDiff, mutateSecuritySchemeDiff, mutateServerDiff, mutateTagDiff } from "../libs/watch-mode.js";
import { watch } from "vue";
import { useToasts } from "@scalar/use-toasts";
import { createHash, fetchDocument } from "@scalar/oas-utils/helpers";
import { parseSchema } from "@scalar/oas-utils/transforms";
import { useTimeoutPoll } from "@vueuse/core";
import microdiff from "microdiff";
//#region src/views/Request/hooks/useOpenApiWatcher.ts
/** Timeout for the watch mode polling */
var POLLING_INTERVAL = 5 * 1e3;
/** Pause for 60 seconds after an error */
var ERROR_TIMEOUT = 60 * 1e3;
/**
* Hook which handles polling the documentUrl for changes then attempts to merge what is new
*
* TODO:
* - check lastModified or similar headers
* - speed up the polling when there's a change then slowly slow it down
*/
var useOpenApiWatcher = () => {
	const { toast } = useToasts();
	const activeEntities = useActiveEntities();
	const store = useWorkspace();
	const { activeCollection, activeWorkspace } = activeEntities;
	const { collectionMutators } = store;
	/** Little toast helper */
	const toastError = (type) => toast(`[useOpenApiWatcher] Changes to the ${type} were not applied`, "error");
	const applyDiff = (d) => {
		if (d.path[0] === "info" || d.path[0] === "security") {
			if (!mutateCollectionDiff(d, activeEntities, store)) toastError("collection");
		} else if (d.path[0] === "components" && d.path[1] === "securitySchemes") {
			if (!mutateSecuritySchemeDiff(d, activeEntities, store)) toastError("securitySchemes");
		} else if (d.path[0] === "servers") {
			if (!mutateServerDiff(d, activeEntities, store)) toastError("servers");
		} else if (d.path[0] === "tags") {
			if (!mutateTagDiff(d, activeEntities, store)) toastError("tags");
		} else if (d.path[0] === "paths") {
			if (!mutateRequestDiff(d, activeEntities, store)) toastError("requests");
		}
	};
	const { pause, resume } = useTimeoutPoll(async () => {
		const url = activeCollection.value?.documentUrl;
		if (!url) return;
		const old = specDictionary[url];
		try {
			const spec = await fetchDocument(url, activeWorkspace.value?.proxyUrl, void 0, false);
			const hash = createHash(spec);
			collectionMutators.edit(activeCollection.value.uid, "watchModeStatus", "WATCHING");
			if (!old?.hash) {
				const { schema } = await parseSchema(spec);
				if (schema) specDictionary[url] = {
					hash,
					schema
				};
			} else if (old.hash && old.hash !== hash) {
				const { schema } = await parseSchema(spec);
				const combined = combineRenameDiffs(microdiff(old.schema, schema));
				try {
					combined.forEach(applyDiff);
					specDictionary[url] = {
						hash,
						schema
					};
				} catch (e) {
					console.error("[useOpenApiWatcher] Error:", e);
				}
			} else console.log("[useOpenApiWatcher] No changes detected yet…");
		} catch (e) {
			console.error("[useOpenApiWatcher] Error:", e);
			console.info("[useOpenApiWatcher] Pausing watcher for 60 seconds");
			pause();
			collectionMutators.edit(activeCollection.value.uid, "watchModeStatus", "ERROR");
			toast("[useOpenApiWatcher] Unable to fetch the spec file, paused the watcher for 60 seconds", "error");
			setTimeout(() => {
				console.info("[useOpenApiWatcher] Resuming watcher");
				resume();
			}, ERROR_TIMEOUT);
		}
	}, POLLING_INTERVAL);
	watch([() => activeCollection.value?.documentUrl, () => activeCollection.value?.watchMode], ([documentUrl, watchMode]) => {
		if (documentUrl && watchMode) {
			console.info(`[useOpenApiWatcher] Watching ${documentUrl} …`);
			resume();
		} else if (activeCollection.value) {
			pause();
			collectionMutators.edit(activeCollection.value.uid, "watchModeStatus", "IDLE");
		}
	}, { immediate: true });
};
//#endregion
export { useOpenApiWatcher };

//# sourceMappingURL=useOpenApiWatcher.js.map