"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_GRANTEE_BINDING = exports.VALID_GRANTEE_BINDINGS = exports.DEFAULT_PRIVATE_STATE_BACKEND = exports.VALID_PRIVATE_STATE_BACKENDS = exports.DEFAULT_ZK_CONFIG_BASE = exports.DEFAULT_PROOF_SERVER_URL = exports.DEFAULT_INDEXER_URLS = exports.DEFAULT_NODE_URL = exports.DEFAULT_NETWORK = exports.VALID_NIGHTGATE_NETWORKS = void 0;
exports.getNightgatePluginConfig = getNightgatePluginConfig;
exports.getConfiguredPrivateStateBackend = getConfiguredPrivateStateBackend;
exports.getConfiguredGranteeBinding = getConfiguredGranteeBinding;
exports.getConfiguredNightgateNetwork = getConfiguredNightgateNetwork;
exports.getConfiguredNightgateNodeUrl = getConfiguredNightgateNodeUrl;
exports.getConfiguredNightgateCrawlerNodeUrl = getConfiguredNightgateCrawlerNodeUrl;
exports.isNightgatePluginConfigured = isNightgatePluginConfigured;
exports.normalizeNightgateNetwork = normalizeNightgateNetwork;
exports.resolveSubmissionEndpoints = resolveSubmissionEndpoints;
exports.resolveNightgateRuntimeConfig = resolveNightgateRuntimeConfig;
exports.mainnetSubmissionBlockReason = mainnetSubmissionBlockReason;
const cds_1 = __importDefault(require("@sap/cds"));
exports.VALID_NIGHTGATE_NETWORKS = ['testnet', 'preprod', 'mainnet'];
/**
 * Single-cast accessor for the plugin's CAP config block.
 *
 * `cds.env` is typed as a freeform object by CAP (it merges package.json,
 * .cdsrc, and env vars at runtime, so the shape is genuinely dynamic).
 * Rather than scattering `(cds.env as any).requires?.nightgate` across every
 * callsite — which we did before and got rightly called out for — the cast
 * lives ONCE here and every other site reads a properly typed
 * `NightgatePluginConfig` via this function.
 */
function getNightgatePluginConfig() {
    const env = cds_1.default.env;
    return env.requires?.nightgate ?? {};
}
exports.DEFAULT_NETWORK = 'preprod';
exports.DEFAULT_NODE_URL = 'wss://rpc.preprod.midnight.network/';
exports.DEFAULT_INDEXER_URLS = {
    preprod: {
        http: 'https://indexer.preprod.midnight.network/api/v4/graphql',
        ws: 'wss://indexer.preprod.midnight.network/api/v4/graphql/ws'
    },
    testnet: {
        http: 'http://localhost:8088/api/v4/graphql',
        ws: 'ws://localhost:8088/api/v4/graphql/ws'
    },
    mainnet: {
        http: 'https://indexer.midnight.network/api/v4/graphql',
        ws: 'wss://indexer.midnight.network/api/v4/graphql/ws'
    }
};
exports.DEFAULT_PROOF_SERVER_URL = 'http://localhost:6300';
exports.DEFAULT_ZK_CONFIG_BASE = './contracts';
exports.VALID_PRIVATE_STATE_BACKENDS = ['cap-db', 'level'];
exports.DEFAULT_PRIVATE_STATE_BACKEND = 'cap-db';
function getConfiguredPrivateStateBackend(config) {
    const raw = readEnv('NIGHTGATE_PRIVATE_STATE_BACKEND') || config?.privateStateBackend;
    if (raw && exports.VALID_PRIVATE_STATE_BACKENDS.includes(raw)) {
        return raw;
    }
    return exports.DEFAULT_PRIVATE_STATE_BACKEND;
}
exports.VALID_GRANTEE_BINDINGS = ['wallet', 'did', 'custom'];
exports.DEFAULT_GRANTEE_BINDING = 'wallet';
function getConfiguredGranteeBinding(config) {
    const raw = readEnv('NIGHTGATE_GRANTEE_BINDING') || config?.granteeBinding;
    if (raw && exports.VALID_GRANTEE_BINDINGS.includes(raw)) {
        return raw;
    }
    return exports.DEFAULT_GRANTEE_BINDING;
}
function readEnv(key) {
    return process.env[key]?.trim() || undefined;
}
function parseIntEnv(key) {
    const raw = readEnv(key);
    if (raw == null)
        return undefined;
    const n = Number.parseInt(raw, 10);
    return Number.isFinite(n) && n > 0 ? n : undefined;
}
function getConfiguredNightgateNetwork(config) {
    return readEnv('NIGHTGATE_NETWORK') || config?.network;
}
function getConfiguredNightgateNodeUrl(config) {
    return readEnv('NIGHTGATE_NODE_URL') || config?.nodeUrl;
}
function getConfiguredNightgateCrawlerNodeUrl(config) {
    return readEnv('NIGHTGATE_CRAWLER_NODE_URL') || config?.crawler?.nodeUrl;
}
function isNightgatePluginConfigured(config) {
    if (!config) {
        return false;
    }
    const configuredNetwork = getConfiguredNightgateNetwork(config);
    if (config.kind === 'nightgate' && !configuredNetwork) {
        return false;
    }
    return Boolean(config.kind === 'nightgate' || configuredNetwork);
}
function normalizeNightgateNetwork(network) {
    if (network && exports.VALID_NIGHTGATE_NETWORKS.includes(network)) {
        return { network: network };
    }
    if (network) {
        return {
            network: exports.DEFAULT_NETWORK,
            invalidNetwork: network
        };
    }
    return { network: exports.DEFAULT_NETWORK };
}
function resolveSubmissionEndpoints(network, config) {
    const defaults = exports.DEFAULT_INDEXER_URLS[network];
    return {
        indexerHttpUrl: readEnv('NIGHTGATE_INDEXER_HTTP_URL') || config?.indexerHttpUrl || defaults.http,
        indexerWsUrl: readEnv('NIGHTGATE_INDEXER_WS_URL') || config?.indexerWsUrl || defaults.ws,
        proofServerUrl: readEnv('NIGHTGATE_PROOF_SERVER_URL') || config?.proofServerUrl || exports.DEFAULT_PROOF_SERVER_URL,
        zkConfigBasePath: readEnv('NIGHTGATE_ZK_CONFIG_BASE') || config?.zkConfigBasePath || exports.DEFAULT_ZK_CONFIG_BASE
    };
}
function resolveNightgateRuntimeConfig(config = {}) {
    const rawCrawlerConfig = config.crawler || {};
    // env-var overrides for crawler tuning. Numeric vars are parsed; anything
    // unparseable falls back to the config value (or built-in default).
    const fetchConcurrencyEnv = parseIntEnv('NIGHTGATE_FETCH_CONCURRENCY');
    const rpcBatchSizeEnv = parseIntEnv('NIGHTGATE_RPC_BATCH_SIZE');
    // NIGHTGATE_CRAWLER_ENABLED=false disables the crawler at boot. Useful for
    // running submission tests in isolation so the wallet sync isn't competing
    // with block ingestion for CPU/RAM on the same event loop.
    const crawlerEnabledEnv = readEnv('NIGHTGATE_CRAWLER_ENABLED');
    const crawlerEnabledOverride = crawlerEnabledEnv == null
        ? undefined
        : !/^(false|0|no|off)$/i.test(crawlerEnabledEnv);
    const crawlerConfig = {
        ...rawCrawlerConfig,
        ...(fetchConcurrencyEnv != null && { fetchConcurrency: fetchConcurrencyEnv }),
        ...(rpcBatchSizeEnv != null && { rpcBatchSize: rpcBatchSizeEnv }),
        ...(crawlerEnabledOverride != null && { enabled: crawlerEnabledOverride })
    };
    const configuredNetwork = getConfiguredNightgateNetwork(config);
    const { network, invalidNetwork } = normalizeNightgateNetwork(configuredNetwork);
    const nodeUrl = getConfiguredNightgateNodeUrl(config) || exports.DEFAULT_NODE_URL;
    const crawlerNodeUrl = getConfiguredNightgateCrawlerNodeUrl(config) || nodeUrl;
    const submissionEndpoints = resolveSubmissionEndpoints(network, config);
    return {
        network,
        nodeUrl,
        crawlerConfig,
        crawlerNodeUrl,
        submissionEndpoints,
        invalidNetwork
    };
}
/**
 * Mainnet submission safety gate. Returns a human-readable rejection reason when
 * the resolved network is `mainnet` and `allowMainnetSubmission` is not explicitly
 * true; otherwise null (submission allowed). Used by every on-chain submission
 * action handler to fail fast before building/submitting a transaction.
 */
function mainnetSubmissionBlockReason(config) {
    const { network } = resolveNightgateRuntimeConfig(config);
    if (network === 'mainnet' && config.allowMainnetSubmission !== true) {
        return 'Mainnet submission is disabled. Set cds.requires.nightgate.allowMainnetSubmission=true ' +
            'to enable it. Mainnet has known submission instability (1016 Immediately Dropped, ' +
            'forum thread 1190); read-only indexing is unaffected.';
    }
    return null;
}
