"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEnv = exports.isNode = exports.isDeno = exports.isJsDom = exports.isWebWorker = exports.isBrowser = void 0;
exports.getRuntimeEnvironment = getRuntimeEnvironment;
exports.getLangSmithEnvVarsMetadata = getLangSmithEnvVarsMetadata;
exports.getLangSmithEnvironmentVariables = getLangSmithEnvironmentVariables;
exports.getEnvironmentVariable = getEnvironmentVariable;
exports.getLangSmithEnvironmentVariable = getLangSmithEnvironmentVariable;
exports.setEnvironmentVariable = setEnvironmentVariable;
exports.getShas = getShas;
exports.getOtelEnabled = getOtelEnabled;
exports.resolveTracingMode = resolveTracingMode;
// Inlined from https://github.com/flexdinesh/browser-or-node
const index_js_1 = require("../index.cjs");
let globalEnv;
const isBrowser = () => typeof window !== "undefined" && typeof window.document !== "undefined";
exports.isBrowser = isBrowser;
const isWebWorker = () => typeof globalThis === "object" &&
    globalThis.constructor &&
    globalThis.constructor.name === "DedicatedWorkerGlobalScope";
exports.isWebWorker = isWebWorker;
const isJsDom = () => (typeof window !== "undefined" && window.name === "nodejs") ||
    (typeof navigator !== "undefined" && navigator.userAgent.includes("jsdom"));
exports.isJsDom = isJsDom;
// Supabase Edge Function provides a `Deno` global object
// without `version` property
const isDeno = () => typeof globalThis.Deno !== "undefined";
exports.isDeno = isDeno;
// Mark not-as-node if in Supabase Edge Function
const isNode = () => typeof process !== "undefined" &&
    typeof process.versions !== "undefined" &&
    typeof process.versions.node !== "undefined" &&
    !(0, exports.isDeno)();
exports.isNode = isNode;
const getEnv = () => {
    if (globalEnv) {
        return globalEnv;
    }
    // @ts-expect-error Bun types are not imported due to conflicts with Node types
    if (typeof Bun !== "undefined") {
        globalEnv = "bun";
    }
    else if ((0, exports.isBrowser)()) {
        globalEnv = "browser";
    }
    else if ((0, exports.isNode)()) {
        globalEnv = "node";
    }
    else if ((0, exports.isWebWorker)()) {
        globalEnv = "webworker";
    }
    else if ((0, exports.isJsDom)()) {
        globalEnv = "jsdom";
    }
    else if ((0, exports.isDeno)()) {
        globalEnv = "deno";
    }
    else {
        globalEnv = "other";
    }
    return globalEnv;
};
exports.getEnv = getEnv;
let runtimeEnvironment;
function getRuntimeEnvironment() {
    if (runtimeEnvironment === undefined) {
        const env = (0, exports.getEnv)();
        const releaseEnv = getShas();
        runtimeEnvironment = {
            library: "langsmith",
            runtime: env,
            sdk: "langsmith-js",
            sdk_version: index_js_1.__version__,
            ...releaseEnv,
        };
    }
    return runtimeEnvironment;
}
/**
 * Retrieves the LangSmith-specific metadata from the current runtime environment.
 *
 * @returns {Record<string, string>}
 *  - A record of LangSmith-specific metadata environment variables.
 */
function getLangSmithEnvVarsMetadata() {
    const allEnvVars = getLangSmithEnvironmentVariables();
    const envVars = {};
    const excluded = [
        "LANGCHAIN_API_KEY",
        "LANGCHAIN_ENDPOINT",
        "LANGCHAIN_TRACING_V2",
        "LANGCHAIN_PROJECT",
        "LANGCHAIN_SESSION",
        "LANGSMITH_API_KEY",
        "LANGSMITH_ENDPOINT",
        "LANGSMITH_TRACING_V2",
        "LANGSMITH_CONFIG_FILE",
        "LANGSMITH_PROJECT",
        "LANGSMITH_SESSION",
    ];
    for (const [key, value] of Object.entries(allEnvVars)) {
        if (typeof value === "string" &&
            !excluded.includes(key) &&
            !key.toLowerCase().includes("key") &&
            !key.toLowerCase().includes("secret") &&
            !key.toLowerCase().includes("token")) {
            if (key === "LANGCHAIN_REVISION_ID") {
                envVars["revision_id"] = value;
            }
            else {
                envVars[key] = value;
            }
        }
    }
    return envVars;
}
/**
 * Retrieves only the LangChain/LangSmith-prefixed environment variables from the current runtime environment.
 * This is more efficient than copying all environment variables.
 *
 * @returns {Record<string, string>}
 *  - A record of LangChain/LangSmith environment variables.
 */
function getLangSmithEnvironmentVariables() {
    const envVars = {};
    try {
        // Check for Node.js environment
        // eslint-disable-next-line no-process-env
        if (typeof process !== "undefined" && process.env) {
            // eslint-disable-next-line no-process-env
            for (const [key, value] of Object.entries(process.env)) {
                if ((key.startsWith("LANGCHAIN_") || key.startsWith("LANGSMITH_")) &&
                    value != null) {
                    if ((key.toLowerCase().includes("key") ||
                        key.toLowerCase().includes("secret") ||
                        key.toLowerCase().includes("token")) &&
                        typeof value === "string") {
                        envVars[key] =
                            value.slice(0, 2) +
                                "*".repeat(value.length - 4) +
                                value.slice(-2);
                    }
                    else {
                        envVars[key] = value;
                    }
                }
            }
        }
    }
    catch (_e) {
        // Catch any errors that might occur while trying to access environment variables
    }
    return envVars;
}
function getEnvironmentVariable(name) {
    // Certain Deno setups will throw an error if you try to access environment variables
    // https://github.com/hwchase17/langchainjs/issues/1412
    try {
        return typeof process !== "undefined"
            ? // eslint-disable-next-line no-process-env
                process.env?.[name]
            : undefined;
    }
    catch (_e) {
        return undefined;
    }
}
function getLangSmithEnvironmentVariable(name) {
    return (getEnvironmentVariable(`LANGSMITH_${name}`) ||
        getEnvironmentVariable(`LANGCHAIN_${name}`));
}
function setEnvironmentVariable(name, value) {
    if (typeof process !== "undefined") {
        // eslint-disable-next-line no-process-env
        process.env[name] = value;
    }
}
let cachedCommitSHAs;
/**
 * Get the Git commit SHA from common environment variables
 * used by different CI/CD platforms.
 * @returns {string | undefined} The Git commit SHA or undefined if not found.
 */
function getShas() {
    if (cachedCommitSHAs !== undefined) {
        return cachedCommitSHAs;
    }
    const common_release_envs = [
        "VERCEL_GIT_COMMIT_SHA",
        "NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA",
        "COMMIT_REF",
        "RENDER_GIT_COMMIT",
        "CI_COMMIT_SHA",
        "CIRCLE_SHA1",
        "CF_PAGES_COMMIT_SHA",
        "REACT_APP_GIT_SHA",
        "SOURCE_VERSION",
        "GITHUB_SHA",
        "TRAVIS_COMMIT",
        "GIT_COMMIT",
        "BUILD_VCS_NUMBER",
        "bamboo_planRepository_revision",
        "Build.SourceVersion",
        "BITBUCKET_COMMIT",
        "DRONE_COMMIT_SHA",
        "SEMAPHORE_GIT_SHA",
        "BUILDKITE_COMMIT",
    ];
    const shas = {};
    for (const env of common_release_envs) {
        const envVar = getEnvironmentVariable(env);
        if (envVar !== undefined) {
            shas[env] = envVar;
        }
    }
    cachedCommitSHAs = shas;
    return shas;
}
function getOtelEnabled() {
    return (getEnvironmentVariable("OTEL_ENABLED") === "true" ||
        getLangSmithEnvironmentVariable("OTEL_ENABLED") === "true");
}
const _VALID_TRACING_MODES = new Set(["langsmith", "otel"]);
/**
 * Resolve the effective tracing mode from an explicit config value and
 * environment variables.
 *
 * Priority: explicit argument > `LANGSMITH_TRACING_MODE` env var >
 * legacy `OTEL_ENABLED` / `LANGSMITH_OTEL_ENABLED` env vars > `"langsmith"`.
 */
function resolveTracingMode(configValue) {
    if (configValue !== undefined) {
        return configValue;
    }
    const envMode = getLangSmithEnvironmentVariable("TRACING_MODE");
    if (envMode !== undefined && envMode !== "") {
        const lower = envMode.toLowerCase();
        if (!_VALID_TRACING_MODES.has(lower)) {
            throw new Error(`Invalid LANGSMITH_TRACING_MODE=${JSON.stringify(envMode)}. ` +
                `Must be one of: ${[..._VALID_TRACING_MODES].sort().join(", ")}`);
        }
        if (getOtelEnabled()) {
            console.warn("Both LANGSMITH_TRACING_MODE and the legacy OTEL_ENABLED / " +
                "LANGSMITH_OTEL_ENABLED env vars are set. " +
                "LANGSMITH_TRACING_MODE takes precedence.");
        }
        return lower;
    }
    // Fall back to legacy env var
    if (getOtelEnabled()) {
        return "otel";
    }
    return "langsmith";
}
