"use strict";
/*
 * @adonisjs/hash
 *
 * (c) Harminder Virk <virk@adonisjs.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.Hash = void 0;
/// <reference path="../../adonis-typings/hash.ts" />
const manager_1 = require("@poppinss/manager");
const utils_1 = require("@poppinss/utils");
/**
 * The Hash module exposes the API to hash values using an underlying
 * Hash driver.
 */
class Hash extends manager_1.Manager {
    constructor(application, config) {
        super(application);
        this.config = config;
        this.singleton = true;
        this.validateConfig();
    }
    /**
     * A boolean to know, if hash module is running in fake
     * mode or not
     */
    get isFaked() {
        return !!this.fakeDriver;
    }
    /**
     * Validate config
     */
    validateConfig() {
        const validator = new utils_1.ManagerConfigValidator(this.config, 'hash', 'config/hash');
        validator.validateDefault('default');
        validator.validateList('list', 'default');
    }
    /**
     * Pulling the default driver name from the user config.
     */
    getDefaultMappingName() {
        return this.config.default;
    }
    /**
     * Returns the config for a mapping
     */
    getMappingConfig(name) {
        return this.config.list[name];
    }
    /**
     * Returns the driver name for a mapping
     */
    getMappingDriver(name) {
        const config = this.getMappingConfig(name);
        return config ? config.driver : undefined;
    }
    /**
     * Creating bcrypt driver. The manager will call this method anytime
     * someone will ask for the `bcrypt` driver.
     */
    createBcrypt(_, config) {
        const { Bcrypt } = require('../Drivers/Bcrypt');
        return new Bcrypt(config);
    }
    /**
     * Creating argon driver. The manager will call this method anytime
     * someone will ask for the `argon` driver.
     */
    createArgon2(_, config) {
        const { Argon } = require('../Drivers/Argon');
        return new Argon(config);
    }
    /**
     * Creating scrypt driver. The manager will call this method anytime
     * someone will ask for the `scrypt` driver.
     */
    createScrypt(_, config) {
        const { Scrypt } = require('../Drivers/Scrypt');
        return new Scrypt(config);
    }
    /**
     * Creating fake driver. The manager will call this method anytime
     * someone will ask for the `fake` driver.
     */
    createFake() {
        const { Fake } = require('../Drivers/Fake');
        return new Fake();
    }
    /**
     * Initiate faking hash calls. All methods invoked on the main hash
     * module and the underlying drivers will be faked using the
     * fake driver.
     *
     * To restore the fake. Run the `Hash.restore` method.
     */
    fake() {
        this.fakeDriver = this.fakeDriver || this.createFake();
    }
    /**
     * Restore fake
     */
    restore() {
        this.fakeDriver = undefined;
    }
    /**
     * Hash value using the default driver
     */
    make(value) {
        if (this.fakeDriver) {
            return this.fakeDriver.make(value);
        }
        return this.use().make(value);
    }
    /**
     * Verify value using the default driver
     */
    verify(hashedValue, plainValue) {
        if (this.fakeDriver) {
            return this.fakeDriver.verify(hashedValue, plainValue);
        }
        return this.use().verify(hashedValue, plainValue);
    }
    /**
     * Find if value needs to be re-hashed as per the default driver.
     */
    needsReHash(hashedValue) {
        if (this.fakeDriver) {
            return this.fakeDriver.needsReHash(hashedValue);
        }
        const driver = this.use();
        if (typeof driver.needsReHash !== 'function') {
            return false;
        }
        return driver.needsReHash(hashedValue);
    }
    /**
     * Pull pre-configured driver instance
     */
    use(name) {
        if (this.fakeDriver) {
            return this.fakeDriver;
        }
        return (name ? super.use(name) : super.use());
    }
}
exports.Hash = Hash;
