"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
const path_1 = __importDefault(require("path"));
const virtual_stats_1 = require("./virtual-stats");
let inode = 45000000;
const ALL = 'all';
const STATIC = 'static';
const DYNAMIC = 'dynamic';
function checkActivation(instance) {
    if (!instance._compiler) {
        throw new Error('You must use this plugin only after creating webpack instance!');
    }
}
function getModulePath(filePath, compiler) {
    return path_1.default.isAbsolute(filePath) ? filePath : path_1.default.join(compiler.context, filePath);
}
function createWebpackData(result) {
    return (backendOrStorage) => {
        if (backendOrStorage._data) {
            const curLevelIdx = backendOrStorage._currentLevel;
            const curLevel = backendOrStorage._levels[curLevelIdx];
            return {
                result,
                level: curLevel,
            };
        }
        return [null, result];
    };
}
function getData(storage, key) {
    if (storage._data instanceof Map) {
        return storage._data.get(key);
    }
    else if (storage._data) {
        return storage.data[key];
    }
    else if (storage.data instanceof Map) {
        return storage.data.get(key);
    }
    else {
        return storage.data[key];
    }
}
function setData(backendOrStorage, key, valueFactory) {
    const value = valueFactory(backendOrStorage);
    if (backendOrStorage._data instanceof Map) {
        backendOrStorage._data.set(key, value);
    }
    else if (backendOrStorage._data) {
        backendOrStorage.data[key] = value;
    }
    else if (backendOrStorage.data instanceof Map) {
        backendOrStorage.data.set(key, value);
    }
    else {
        backendOrStorage.data[key] = value;
    }
}
function getStatStorage(fileSystem) {
    if (fileSystem._statStorage) {
        return fileSystem._statStorage;
    }
    else if (fileSystem._statBackend) {
        return fileSystem._statBackend;
    }
    else {
        throw new Error("Couldn't find a stat storage");
    }
}
function getFileStorage(fileSystem) {
    if (fileSystem._readFileStorage) {
        return fileSystem._readFileStorage;
    }
    else if (fileSystem._readFileBackend) {
        return fileSystem._readFileBackend;
    }
    else {
        throw new Error("Couldn't find a readFileStorage");
    }
}
function getReadDirBackend(fileSystem) {
    if (fileSystem._readdirBackend) {
        return fileSystem._readdirBackend;
    }
    else if (fileSystem._readdirStorage) {
        return fileSystem._readdirStorage;
    }
    else {
        throw new Error("Couldn't find a readDirStorage from Webpack Internals");
    }
}
function getRealpathBackend(fileSystem) {
    if (fileSystem._realpathBackend) {
        return fileSystem._realpathBackend;
    }
}
class VirtualModulesPlugin {
    constructor(modules) {
        this._compiler = null;
        this._watcher = null;
        this._staticModules = modules || null;
    }
    getModuleList(filter = ALL) {
        var _a, _b;
        let modules = {};
        const shouldGetStaticModules = filter === ALL || filter === STATIC;
        const shouldGetDynamicModules = filter === ALL || filter === DYNAMIC;
        if (shouldGetStaticModules) {
            modules = Object.assign(Object.assign({}, modules), this._staticModules);
        }
        if (shouldGetDynamicModules) {
            const finalInputFileSystem = (_a = this._compiler) === null || _a === void 0 ? void 0 : _a.inputFileSystem;
            const virtualFiles = (_b = finalInputFileSystem === null || finalInputFileSystem === void 0 ? void 0 : finalInputFileSystem._virtualFiles) !== null && _b !== void 0 ? _b : {};
            const dynamicModules = {};
            Object.keys(virtualFiles).forEach((key) => {
                dynamicModules[key] = virtualFiles[key].contents;
            });
            modules = Object.assign(Object.assign({}, modules), dynamicModules);
        }
        return modules;
    }
    writeModule(filePath, contents) {
        if (!this._compiler) {
            throw new Error(`Plugin has not been i