import { AssertionError } from "node:assert";
import { RuntimeException } from "@poppinss/utils/exception";
import { debuglog } from "node:util";
var Hash = class {
	#driver;
	constructor(driver) {
		this.#driver = driver;
	}
	isValidHash(value) {
		return this.#driver.isValidHash(value);
	}
	make(value) {
		return this.#driver.make(value);
	}
	verify(hashedValue, plainValue) {
		return this.#driver.verify(hashedValue, plainValue);
	}
	needsReHash(hashedValue) {
		return this.#driver.needsReHash(hashedValue);
	}
	async assertEquals(hashedValue, plainValue) {
		if (!await this.#driver.verify(hashedValue, plainValue)) throw new AssertionError({
			message: `Expected "${plainValue}" to pass hash verification`,
			expected: true,
			actual: false,
			operator: "strictEqual",
			stackStartFn: this.assertEquals
		});
	}
	async assertNotEquals(hashedValue, plainValue) {
		if (await this.#driver.verify(hashedValue, plainValue)) throw new AssertionError({
			message: `Expected "${plainValue}" to fail hash verification`,
			expected: false,
			actual: true,
			operator: "strictEqual",
			stackStartFn: this.assertNotEquals
		});
	}
};
var debug_default = debuglog("adonisjs:hash");
var Fake = class {
	isValidHash(_) {
		return true;
	}
	async make(value) {
		return value;
	}
	async verify(hashedValue, plainValue) {
		return hashedValue === plainValue;
	}
	needsReHash(_) {
		return false;
	}
};
var HashManager = class {
	#fakeHasher;
	#hashersCache = {};
	config;
	constructor(config) {
		this.config = config;
		debug_default("creating hash manager. config: %O", this.config);
	}
	use(hasher) {
		let hasherToUse = hasher || this.config.default;
		if (!hasherToUse) throw new RuntimeException("Cannot create hash instance. No default hasher is defined in the config");
		if (this.#fakeHasher) return this.#fakeHasher;
		const cachedHasher = this.#hashersCache[hasherToUse];
		if (cachedHasher) {
			debug_default("using hasher from cache. name: \"%s\"", hasherToUse);
			return cachedHasher;
		}
		const driverFactory = this.config.list[hasherToUse];
		debug_default("creating hash driver. name: \"%s\"", hasherToUse);
		const hash = new Hash(driverFactory());
		this.#hashersCache[hasherToUse] = hash;
		return hash;
	}
	fake() {
		debug_default("enabling fakes");
		if (!this.#fakeHasher) this.#fakeHasher = new Hash(new Fake());
		return { [Symbol.dispose]: () => this.restore() };
	}
	restore() {
		debug_default("restoring fakes");
		this.#fakeHasher = void 0;
	}
	isValidHash(value) {
		return this.use().isValidHash(value);
	}
	make(value) {
		return this.use().make(value);
	}
	verify(hashedValue, plainValue) {
		return this.use().verify(hashedValue, plainValue);
	}
	needsReHash(hashedValue) {
		return this.use().needsReHash(hashedValue);
	}
	async assertEquals(hashedValue, plainValue) {
		return this.use().assertEquals(hashedValue, plainValue);
	}
	async assertNotEquals(hashedValue, plainValue) {
		return this.use().assertNotEquals(hashedValue, plainValue);
	}
};
export { Hash as n, HashManager as t };
