import { M, T } from "../../../../../tinyspy@4.0.4/node_modules/tinyspy/dist/index.js";

//#region ../../node_modules/.pnpm/@vitest+spy@3.2.4/node_modules/@vitest/spy/dist/index.js
const mocks = /* @__PURE__ */ new Set();
function isMockFunction(fn$1) {
	return typeof fn$1 === "function" && "_isMockFunction" in fn$1 && fn$1._isMockFunction;
}
function spyOn(obj, method, accessType) {
	const objMethod = accessType ? { [{
		get: "getter",
		set: "setter"
	}[accessType]]: method } : method;
	let state;
	const descriptor = getDescriptor(obj, method);
	const fn$1 = descriptor && descriptor[accessType || "value"];
	if (isMockFunction(fn$1)) state = fn$1.mock._state();
	try {
		const spy = enhanceSpy(M(obj, objMethod));
		if (state) spy.mock._state(state);
		return spy;
	} catch (error) {
		if (error instanceof TypeError && Symbol.toStringTag && obj[Symbol.toStringTag] === "Module" && (error.message.includes("Cannot redefine property") || error.message.includes("Cannot replace module namespace") || error.message.includes("can't redefine non-configurable property"))) throw new TypeError(`Cannot spy on export "${String(objMethod)}". Module namespace is not configurable in ESM. See: https://vitest.dev/guide/browser/#limitations`, { cause: error });
		throw error;
	}
}
let callOrder = 0;
function enhanceSpy(spy) {
	const stub = spy;
	let implementation;
	let onceImplementations = [];
	let implementationChangedTemporarily = false;
	let instances = [];
	let contexts = [];
	let invocations = [];
	const state = T(spy);
	const mockContext = {
		get calls() {
			return state.calls;
		},
		get contexts() {
			return contexts;
		},
		get instances() {
			return instances;
		},
		get invocationCallOrder() {
			return invocations;
		},
		get results() {
			return state.results.map(([callType, value]) => {
				return {
					type: callType === "error" ? "throw" : "return",
					value
				};
			});
		},
		get settledResults() {
			return state.resolves.map(([callType, value]) => {
				return {
					type: callType === "error" ? "rejected" : "fulfilled",
					value
				};
			});
		},
		get lastCall() {
			return state.calls[state.calls.length - 1];
		},
		_state(state$1) {
			if (state$1) {
				implementation = state$1.implementation;
				onceImplementations = state$1.onceImplementations;
				implementationChangedTemporarily = state$1.implementationChangedTemporarily;
			}
			return {
				implementation,
				onceImplementations,
				implementationChangedTemporarily
			};
		}
	};
	function mockCall(...args) {
		instances.push(this);
		contexts.push(this);
		invocations.push(++callOrder);
		return (implementationChangedTemporarily ? implementation : onceImplementations.shift() || implementation || state.getOriginal() || (() => {})).apply(this, args);
	}
	let name = stub.name;
	stub.getMockName = () => name || "vi.fn()";
	stub.mockName = (n) => {
		name = n;
		return stub;
	};
	stub.mockClear = () => {
		state.reset();
		instances = [];
		contexts = [];
		invocations = [];
		return stub;
	};
	stub.mockReset = () => {
		stub.mockClear();
		implementation = void 0;
		onceImplementations = [];
		return stub;
	};
	stub.mockRestore = () => {
		stub.mockReset();
		state.restore();
		return stub;
	};
	if (Symbol.dispose) stub[Symbol.dispose] = () => stub.mockRestore();
	stub.getMockImplementation = () => implementationChangedTemporarily ? implementation : onceImplementations.at(0) || implementation;
	stub.mockImplementation = (fn$1) => {
		implementation = fn$1;
		state.willCall(mockCall);
		return stub;
	};
	stub.mockImplementationOnce = (fn$1) => {
		onceImplementations.push(fn$1);
		return stub;
	};
	function withImplementation(fn$1, cb) {
		const originalImplementation = implementation;
		implementation = fn$1;
		state.willCall(mockCall);
		implementationChangedTemporarily = true;
		const reset = () => {
			implementation = originalImplementation;
			implementationChangedTemporarily = false;
		};
		const result = cb();
		if (typeof result === "object" && result && typeof result.then === "function") return result.then(() => {
			reset();
			return stub;
		});
		reset();
		return stub;
	}
	stub.withImplementation = withImplementation;
	stub.mockReturnThis = () => stub.mockImplementation(function() {
		return this;
	});
	stub.mockReturnValue = (val) => stub.mockImplementation(() => val);
	stub.mockReturnValueOnce = (val) => stub.mockImplementationOnce(() => val);
	stub.mockResolvedValue = (val) => stub.mockImplementation(() => Promise.resolve(val));
	stub.mockResolvedValueOnce = (val) => stub.mockImplementationOnce(() => Promise.resolve(val));
	stub.mockRejectedValue = (val) => stub.mockImplementation(() => Promise.reject(val));
	stub.mockRejectedValueOnce = (val) => stub.mockImplementationOnce(() => Promise.reject(val));
	Object.defineProperty(stub, "mock", { get: () => mockContext });
	state.willCall(mockCall);
	mocks.add(stub);
	return stub;
}
function fn(implementation) {
	const enhancedSpy = enhanceSpy(M({ spy: implementation || function() {} }, "spy"));
	if (implementation) enhancedSpy.mockImplementation(implementation);
	return enhancedSpy;
}
function getDescriptor(obj, method) {
	const objDescriptor = Object.getOwnPropertyDescriptor(obj, method);
	if (objDescriptor) return objDescriptor;
	let currentProto = Object.getPrototypeOf(obj);
	while (currentProto !== null) {
		const descriptor = Object.getOwnPropertyDescriptor(currentProto, method);
		if (descriptor) return descriptor;
		currentProto = Object.getPrototypeOf(currentProto);
	}
}

//#endregion
export { fn, isMockFunction, mocks, spyOn };