var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
    if (kind === "m") throw new TypeError("Private method is not writable");
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
    return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _InfoCache_instances, _InfoCache_options, _InfoCache_pending, _InfoCache_modules, _InfoCache_redirects, _InfoCache_npmPackages, _InfoCache_resolve, _InfoCache_getCached, _InfoCache_queueLoad, _InfoCache_load, _InfoCache_populate;
export async function rootInfo() {
    if (!tmpDir)
        tmpDir = Deno.makeTempDirSync();
    const opts = {
        args: ["info", "--json", "--no-config", "--no-lock"],
        cwd: tmpDir,
        env: { DENO_NO_PACKAGE_JSON: "true" },
        stdout: "piped",
        stderr: "inherit",
    };
    const output = await new Deno.Command(Deno.execPath(), opts).output();
    if (!output.success) {
        throw new Error(`Failed to call 'deno info'`);
    }
    const txt = new TextDecoder().decode(output.stdout);
    return JSON.parse(txt);
}
let tmpDir;
async function info(specifier, options) {
    const args = ["info", "--json"];
    if (!Deno.version.deno.startsWith("1.")) {
        args.push("--allow-import");
    }
    const opts = {
        args,
        cwd: undefined,
        env: { DENO_NO_PACKAGE_JSON: "true" },
        stdout: "piped",
        stderr: "inherit",
    };
    if (typeof options.config === "string") {
        opts.args.push("--config", options.config);
    }
    else {
        opts.args.push("--no-config");
    }
    if (options.importMap) {
        opts.args.push("--import-map", options.importMap);
    }
    if (typeof options.lock === "string") {
        opts.args.push("--lock", options.lock);
    }
    else if (!options.cwd) {
        opts.args.push("--no-lock");
    }
    if (options.nodeModulesDir !== undefined) {
        if (Deno.version.deno.startsWith("1.")) {
            if (options.nodeModulesDir === "auto") {
                opts.args.push("--node-modules-dir");
            }
            else if (options.nodeModulesDir === "manual") {
                opts.args.push("--unstable-byonm");
            }
        }
        else {
            opts.args.push(`--node-modules-dir=${options.nodeModulesDir}`);
        }
    }
    if (options.cwd) {
        opts.cwd = options.cwd;
    }
    else {
        if (!tmpDir)
            tmpDir = Deno.makeTempDirSync();
        opts.cwd = tmpDir;
    }
    opts.args.push(specifier);
    const output = await new Deno.Command(Deno.execPath(), opts).output();
    if (!output.success) {
        throw new Error(`Failed to call 'deno info' on '${specifier}'`);
    }
    const txt = new TextDecoder().decode(output.stdout);
    return JSON.parse(txt);
}
export class InfoCache {
    constructor(options = {}) {
        _InfoCache_instances.add(this);
        _InfoCache_options.set(this, void 0);
        _InfoCache_pending.set(this, null);
        _InfoCache_modules.set(this, new Map());
        _InfoCache_redirects.set(this, new Map());
        _InfoCache_npmPackages.set(this, new Map());
        __classPrivateFieldSet(this, _InfoCache_options, options, "f");
    }
    async get(specifier) {
        let entry = __classPrivateFieldGet(this, _InfoCache_instances, "m", _InfoCache_getCached).call(this, specifier);
        if (entry !== undefined)
            return entry;
        await __classPrivateFieldGet(this, _InfoCache_instances, "m", _InfoCache_queueLoad).call(this, specifier);
        entry = __classPrivateFieldGet(this, _InfoCache_instances, "m", _InfoCache_getCached).call(this, specifier);
        if (entry === undefined) {
            throw new Error(`Unreachable: '${specifier}' loaded but not reachable`);
        }
        return entry;
    }
    getNpmPackage(id) {
        return __classPrivateFieldGet(this, _InfoCache_npmPackages, "f").get(id);
    }
}
_InfoCache_options = new WeakMap(), _InfoCache_pending = new WeakMap(), _InfoCache_modules = new WeakMap(), _InfoCache_redirects = new WeakMap(), _InfoCache_npmPackages = new WeakMap(), _InfoCache_instances = new WeakSet(), _InfoCache_resolve = function _InfoCache_resolve(specifier) {
    const original = specifier;
    let counter = 0;
    while (counter++ < 10) {
        const redirect = __classPrivateFieldGet(this, _InfoCache_redirects, "f").get(specifier);
        if (redirect === undefined)
            return specifier;
        specifier = redirect;
    }
    throw new Error(`Too many redirects for '${original}'`);
}, _InfoCache_getCached = function _InfoCache_getCached(specifier) {
    specifier = __classPrivateFieldGet(this, _InfoCache_instances, "m", _InfoCache_resolve).call(this, specifier);
    return __classPrivateFieldGet(this, _InfoCache_modules, "f").get(specifier);
}, _InfoCache_queueLoad = async function _InfoCache_queueLoad(specifier) {
    while (true) {
        if (__classPrivateFieldGet(this, _InfoCache_pending, "f") === null) {
            __classPrivateFieldSet(this, _InfoCache_pending, {
                specifiers: new Set([specifier]),
                done: (async () => {
                    await new Promise((r) => setTimeout(r, 5));
                    const specifiers = __classPrivateFieldGet(this, _InfoCache_pending, "f").specifiers;
                    __classPrivateFieldGet(this, _InfoCache_pending, "f").specifiers = null;
                    await __classPrivateFieldGet(this, _InfoCache_instances, "m", _InfoCache_load).call(this, [...specifiers]);
                    __classPrivateFieldSet(this, _InfoCache_pending, null, "f");
                })(),
            }, "f");
            await __classPrivateFieldGet(this, _InfoCache_pending, "f").done;
            return;
        }
        else if (__classPrivateFieldGet(this, _InfoCache_pending, "f").specifiers !== null) {
            __classPrivateFieldGet(this, _InfoCache_pending, "f").specifiers.add(specifier);
            await __classPrivateFieldGet(this, _InfoCache_pending, "f").done;
            return;
        }
        else {
            await __classPrivateFieldGet(this, _InfoCache_pending, "f").done;
        }
    }
}, _InfoCache_load = async function _InfoCache_load(specifiers) {
    await __classPrivateFieldGet(this, _InfoCache_instances, "m", _InfoCache_populate).call(this, specifiers);
    for (let specifier of specifiers) {
        specifier = __classPrivateFieldGet(this, _InfoCache_instances, "m", _InfoCache_resolve).call(this, specifier);
        const entry = __classPrivateFieldGet(this, _InfoCache_modules, "f").get(specifier);
        if (entry === undefined && specifier.startsWith("npm:")) {
            // we hit https://github.com/denoland/deno/issues/18043, so we have to
            // perform another load to get the actual data of the redirected specifier
            await __classPrivateFieldGet(this, _InfoCache_instances, "m", _InfoCache_populate).call(this, [specifier]);
        }
    }
}, _InfoCache_populate = async function _InfoCache_populate(specifiers) {
    let specifier;
    if (specifiers.length === 1) {
        specifier = specifiers[0];
    }
    else {
        specifier = `data:application/javascript,${encodeURIComponent(specifiers.map((s) => `import ${JSON.stringify(s)};`).join(""))}`;
    }
    const { modules, redirects, npmPackages } = await info(specifier, __classPrivateFieldGet(this, _InfoCache_options, "f"));
    for (const module of modules) {
        if (specifiers.length !== 1 && module.specifier === specifier)
            continue;
        __classPrivateFieldGet(this, _InfoCache_modules, "f").set(module.specifier, module);
    }
    for (const [from, to] of Object.entries(redirects)) {
        __classPrivateFieldGet(this, _InfoCache_redirects, "f").set(from, to);
    }
    if (npmPackages !== undefined) {
        for (const [id, npmPackage] of Object.entries(npmPackages)) {
            __classPrivateFieldGet(this, _InfoCache_npmPackages, "f").set(id, npmPackage);
        }
    }
};
//# sourceMappingURL=deno.js.map