// Copyright Metatype OÜ, licensed under the Mozilla Public License Version 2.0.
// SPDX-License-Identifier: MPL-2.0
import * as dntShim from "../_dnt.shims.js";
import { InheritDef, } from "../typegraph.js";
import { serializeStaticInjection } from "./injection_utils.js";
import { log } from "../io.js";
export function stringifySymbol(symbol) {
    const name = symbol.toString().match(/\((.+)\)/)?.[1];
    if (!name) {
        throw new Error("unable to determine symbol name");
    }
    return name;
}
export function serializeRecordValues(obj) {
    return Object.entries(obj).map(([k, v]) => [k, JSON.stringify(v)]);
}
export function buildReduceData(node, paths = [], currPath = []) {
    if (node === null || node === undefined) {
        throw new Error(`unsupported value "${node}" at ${currPath.join(".")}`);
    }
    if (node instanceof InheritDef) {
        paths.push({
            path: currPath,
            value: { inherit: true, payload: node.payload },
        });
        return paths;
    }
    if (typeof node === "object") {
        if (Array.isArray(node)) {
            paths.push({
                path: currPath,
                value: { inherit: false, payload: serializeStaticInjection(node) },
            });
            return paths;
        }
        for (const [k, v] of Object.entries(node)) {
            buildReduceData(v, paths, [...currPath, k]);
        }
        return paths;
    }
    const allowed = ["number", "string", "boolean"];
    if (allowed.includes(typeof node)) {
        paths.push({
            path: currPath,
            value: { inherit: false, payload: serializeStaticInjection(node) },
        });
        return paths;
    }
    throw new Error(`unsupported type "${typeof node}" at ${currPath.join(".")}`);
}
export function getEnvVariable(key, defaultValue) {
    const glob = dntShim.dntGlobalThis;
    const value = glob?.process
        ? glob?.process.env?.[key]
        : glob?.Deno.env.get(key);
    return value ?? defaultValue;
}
export function getAllEnvVariables() {
    const glob = dntShim.dntGlobalThis;
    return glob?.process ? glob?.process.env : glob?.Deno.env.toObject();
}
const frozenMemo = {};
/** Create a reusable version of a `TypegraphOutput` */
export function freezeTgOutput(config, tgOutput) {
    frozenMemo[tgOutput.name] = frozenMemo[tgOutput.name] ??
        tgOutput.serialize(config);
    return {
        ...tgOutput,
        serialize: () => frozenMemo[tgOutput.name],
    };
}
/**
 * Simple fetch wrapper with more verbose errors
 */
export async function execRequest(url, reqInit, errMsg) {
    try {
        const response = await fetch(url, reqInit);
        if (!response.ok) {
            log.debug("error", response.json());
            throw Error(`${errMsg}: request failed with status ${response.status} (${response.statusText})`);
        }
        if (response.headers.get("Content-Type") == "application/json") {
            return await response.json();
        }
        log.debug("response", response);
        throw Error(`${errMsg}: expected json object, got "${await response.text()}"`);
    }
    catch (err) {
        log.debug("fetch error", { url, requestInit: reqInit, error: err });
        const message = err instanceof Error ? err.message : err;
        throw Error(`${errMsg}: ${message}`);
    }
}
