import { AccountsRoute, AdminDashboardRoute, DashboardRoute, AppApiRoute, StatusPageApiRoute, DocsRoute, HomeRoute, } from "../ServiceRoute";
import BillingConfig from "./BillingConfig";
import Protocol from "../Types/API/Protocol";
import URL from "../Types/API/URL";
import Route from "../Types/API/Route";
import SubscriptionPlan from "../Types/Billing/SubscriptionPlan";
import Email from "../Types/Email";
import ObjectID from "../Types/ObjectID";
import Port from "../Types/Port";
import Hostname from "../Types/API/Hostname";
import ConfigLogLevel from "./Types/ConfigLogLevel";
export const getAllEnvVars = () => {
    return process.env;
};
const FRONTEND_ENV_ALLOW_LIST = [
    "NODE_ENV",
    "HTTP_PROTOCOL",
    "HOST",
    "BILLING_ENABLED",
    "BILLING_PUBLIC_KEY",
    "IS_ENTERPRISE_EDITION",
    "STRIPE_PUBLIC_KEY",
    "VAPID_PUBLIC_KEY",
    "VAPID_SUBJECT",
    "VERSION",
    "STATUS_PAGE_CNAME_RECORD",
    "DASHBOARD_CNAME_RECORD",
    "ANALYTICS_KEY",
    "ANALYTICS_HOST",
    "GIT_SHA",
    "APP_VERSION",
    "OPENTELEMETRY_EXPORTER_OTLP_ENDPOINT",
    "OPENTELEMETRY_EXPORTER_OTLP_HEADERS",
    "DISABLE_TELEMETRY",
    "SLACK_APP_CLIENT_ID",
    "MICROSOFT_TEAMS_APP_CLIENT_ID",
    "GITHUB_APP_CLIENT_ID",
    "GITHUB_APP_NAME",
    "CAPTCHA_ENABLED",
    "CAPTCHA_SITE_KEY",
    "INBOUND_EMAIL_DOMAIN",
];
const FRONTEND_ENV_ALLOW_PREFIXES = [
    "SUBSCRIPTION_PLAN_",
    "PUBLIC_",
];
export const getFrontendEnvVars = () => {
    const frontendEnv = {};
    for (const key of Object.keys(process.env)) {
        const shouldInclude = FRONTEND_ENV_ALLOW_LIST.includes(key) ||
            FRONTEND_ENV_ALLOW_PREFIXES.some((prefix) => {
                return key.startsWith(prefix);
            });
        if (!shouldInclude) {
            continue;
        }
        const value = process.env[key];
        if (typeof value !== "undefined") {
            frontendEnv[key] = value;
        }
    }
    return frontendEnv;
};
const parsePositiveNumberFromEnv = (envKey, fallback) => {
    const rawValue = process.env[envKey];
    if (!rawValue) {
        return fallback;
    }
    const parsedValue = parseFloat(rawValue);
    if (!Number.isFinite(parsedValue) || parsedValue <= 0) {
        return fallback;
    }
    return parsedValue;
};
export const IsBillingEnabled = BillingConfig.IsBillingEnabled;
export const BillingPublicKey = BillingConfig.BillingPublicKey;
export const BillingPrivateKey = BillingConfig.BillingPrivateKey;
export const BillingWebhookSecret = BillingConfig.BillingWebhookSecret;
export const DatabaseHost = Hostname.fromString(process.env["DATABASE_HOST"] || "postgres");
export const LetsEncryptNotificationEmail = Email.fromString(process.env["LETS_ENCRYPT_NOTIFICATION_EMAIL"] || "notifications@example.com");
export const LetsEncryptAccountKey = process.env["LETS_ENCRYPT_ACCOUNT_KEY"] || "";
export const DatabasePort = new Port(process.env["DATABASE_PORT"] || "5432");
export const DatabaseUsername = process.env["DATABASE_USERNAME"] || "postgres";
export const DatabasePassword = process.env["DATABASE_PASSWORD"] || "password";
export const DatabaseName = process.env["DATABASE_NAME"] || "oneuptimedb";
export const DatabaseSslCa = process.env["DATABASE_SSL_CA"] || undefined;
export const DatabaseSslKey = process.env["DATABASE_SSL_KEY"] || undefined;
export const DatabaseSslCert = process.env["DATABASE_SSL_CERT"] || undefined;
export const DatabaseRejectUnauthorized = process.env["DATABASE_SSL_REJECT_UNAUTHORIZED"] === "true";
export const ShouldDatabaseSslEnable = Boolean(DatabaseSslCa || (DatabaseSslCert && DatabaseSslKey));
/*
 * Postgres pool size per API/Worker node. TypeORM's default is 10 which
 * starves the API under any meaningful load — pick a number that, when
 * multiplied by the number of running Node processes, stays under the
 * Postgres server's `max_connections` (default 100 on a stock cluster).
 */
export const MaxPostgresConnections = parseInt(process.env["DATABASE_MAX_OPEN_CONNECTIONS"] || "50", 10);
/*
 * Postgres-side statement timeout (ms). Caps the wall-clock time of any
 * single SQL statement. Without this, a single runaway query can pin a
 * connection forever and starve the pool.
 */
export const PostgresStatementTimeoutMs = parseInt(process.env["DATABASE_STATEMENT_TIMEOUT_MS"] || "30000", 10);
/*
 * Node-postgres client-side query timeout (ms). Belt-and-braces for the
 * server-side statement_timeout — fires even if the connection has gone
 * silent or the server-side timeout doesn't kick in.
 */
export const PostgresQueryTimeoutMs = parseInt(process.env["DATABASE_QUERY_TIMEOUT_MS"] || "30000", 10);
/*
 * Postgres-side idle-in-transaction timeout (ms). Kills connections that
 * are stuck holding row locks inside a BEGIN without committing.
 */
export const PostgresIdleInTransactionTimeoutMs = parseInt(process.env["DATABASE_IDLE_IN_TRANSACTION_TIMEOUT_MS"] || "60000", 10);
/*
 * pg-pool acquire timeout (ms). How long a query waits for a free
 * connection before failing. Without this, requests pile up invisibly
 * when the pool is exhausted.
 */
export const PostgresConnectionAcquireTimeoutMs = parseInt(process.env["DATABASE_CONNECTION_TIMEOUT_MS"] || "5000", 10);
/*
 * pg-pool idle connection timeout (ms). Closes connections that have
 * been sitting unused for this long, freeing server-side slots.
 */
export const PostgresIdleTimeoutMs = parseInt(process.env["DATABASE_IDLE_TIMEOUT_MS"] || "30000", 10);
/*
 * TCP keepalive initial delay (ms) for Postgres sockets. When the client
 * process dies ungracefully (SIGKILL, OOM, crash) or a network partition cuts
 * the link, Postgres has no way to know the client is gone and the backend
 * lingers as an orphaned connection — by default up to the OS
 * tcp_keepalive_time (~2h on Linux). Enabling socket keepalive makes
 * node-postgres probe the peer so dead connections are detected and torn down
 * promptly.
 */
export const PostgresKeepAliveInitialDelayMs = parseInt(process.env["DATABASE_KEEPALIVE_INITIAL_DELAY_MS"] || "10000", 10);
/*
 * Postgres-side idle-session timeout (ms). Server-side backstop for orphaned
 * connections: the server terminates any session that sits idle (outside a
 * transaction) longer than this. MUST be larger than the pool's
 * idleTimeoutMillis (PostgresIdleTimeoutMs) so the pool reaps its own healthy
 * idle connections first and only truly-orphaned sessions (client gone) ever
 * hit this. Set to 0 to disable. Requires Postgres 14+.
 */
export const PostgresIdleSessionTimeoutMs = parseInt(process.env["DATABASE_IDLE_SESSION_TIMEOUT_MS"] || "300000", 10);
/*
 * TypeORM slow-query log threshold (ms). Any query exceeding this is
 * logged so we can find offenders in production without per-query
 * tracing. Set to 0 to disable.
 */
export const PostgresSlowQueryLogThresholdMs = parseInt(process.env["DATABASE_SLOW_QUERY_LOG_THRESHOLD_MS"] || "1000", 10);
export const EncryptionSecret = new ObjectID(process.env["ENCRYPTION_SECRET"] || "secret");
export const OpenSourceDeploymentWebhookUrl = process.env["OPEN_SOURCE_DEPLOYMENT_WEBHOOK_URL"] || "";
export const AirtableApiKey = process.env["AIRTABLE_API_KEY"] || "";
export const AirtableBaseId = process.env["AIRTABLE_BASE_ID"] || "";
export const ClusterKey = new ObjectID(process.env["ONEUPTIME_SECRET"] || "secret");
export const HasClusterKey = Boolean(process.env["ONEUPTIME_SECRET"]);
export const EnableQueueDashboard = process.env["ENABLE_QUEUE_DASHBOARD"] === "true";
export const QueueDashboardSecret = process.env["QUEUE_DASHBOARD_SECRET"] || "";
export const RegisterProbeKey = new ObjectID(process.env["REGISTER_PROBE_KEY"] || "secret");
export const HasRegisterProbeKey = Boolean(process.env["REGISTER_PROBE_KEY"]);
export const AppApiHostname = Hostname.fromString(`${process.env["SERVER_APP_HOSTNAME"] || "localhost"}:${process.env["APP_PORT"] || 80}`);
export const WorkerHostname = Hostname.fromString(`${process.env["SERVER_APP_HOSTNAME"] || "localhost"}:${process.env["APP_PORT"] || 80}`);
export const WorkflowHostname = WorkerHostname;
export const HomeHostname = Hostname.fromString(`${process.env["SERVER_HOME_HOSTNAME"] || "localhost"}:${process.env["HOME_PORT"] || 80}`);
export const Env = process.env["NODE_ENV"] || "production";
// Redis does not require password.
export const RedisHostname = process.env["REDIS_HOST"] || "redis";
export const RedisPort = new Port(process.env["REDIS_PORT"] || "6379");
export const RedisDb = Number(process.env["REDIS_DB"]) || 0;
export const RedisUsername = process.env["REDIS_USERNAME"] || "default";
export const RedisPassword = process.env["REDIS_PASSWORD"] || "password";
export const RedisTlsCa = process.env["REDIS_TLS_CA"] || undefined;
export const RedisTlsCert = process.env["REDIS_TLS_CERT"] || undefined;
export const RedisTlsKey = process.env["REDIS_TLS_KEY"] || undefined;
export const RedisTlsSentinelMode = process.env["REDIS_TLS_SENTINEL_MODE"] === "true";
export const ShouldRedisTlsEnable = Boolean(RedisTlsCa || (RedisTlsCert && RedisTlsKey));
export const RedisIPFamily = process.env["REDIS_IP_FAMILY"]
    ? Number(process.env["REDIS_IP_FAMILY"])
    : 4;
export const IsProduction = process.env["ENVIRONMENT"] === "production";
export const IsDevelopment = process.env["ENVIRONMENT"] === "development";
export const IsTest = process.env["ENVIRONMENT"] === "test";
export const SubscriptionPlans = SubscriptionPlan.getSubscriptionPlans(getAllEnvVars());
export const AnalyticsKey = process.env["ANALYTICS_KEY"] || "";
export const AnalyticsHost = process.env["ANALYTICS_HOST"] || "";
export const DisableAutomaticIncidentCreation = process.env["DISABLE_AUTOMATIC_INCIDENT_CREATION"] === "true";
export const DisableAutomaticAlertCreation = process.env["DISABLE_AUTOMATIC_ALERT_CREATION"] === "true";
export const DisableTelemetryIngestion = process.env["DISABLE_TELEMETRY_INGESTION"] === "true";
/*
 * When true, this process does NOT register any BullMQ queue consumers
 * (the "api" role). Background jobs — telemetry ingestion processing, the
 * general Worker/cron jobs, Workflow runs and Runbook executions — are
 * instead drained by the dedicated "worker" deployment so heavy queue
 * processing never competes with API request handling on the same event
 * loop. Default false → this process consumes queues (backwards compatible
 * single-container behavior). The process still mounts ingest endpoints and
 * enqueues jobs; only consumption is gated.
 */
export const DisableQueueWorkers = process.env["DISABLE_QUEUE_WORKERS"] === "true";
export const ClickhouseHost = Hostname.fromString(process.env["CLICKHOUSE_HOST"] || "clickhouse");
export const StatusPageCNameRecord = process.env["STATUS_PAGE_CNAME_RECORD"] || "";
export const DashboardCNameRecord = process.env["DASHBOARD_CNAME_RECORD"] || "";
export const ClickhousePort = new Port(process.env["CLICKHOUSE_PORT"] || "8123");
export const ClickhouseUsername = process.env["CLICKHOUSE_USER"] || "default";
export const ClickhousePassword = process.env["CLICKHOUSE_PASSWORD"] || "password";
export const ClickhouseDatabase = process.env["CLICKHOUSE_DATABASE"] || "oneuptime";
export const ClickhouseTlsCa = process.env["CLICKHOUSE_TLS_CA"] || undefined;
export const ClickhouseTlsCert = process.env["CLICKHOUSE_TLS_CERT"] || undefined;
export const ClickhouseTlsKey = process.env["CLICKHOUSE_TLS_KEY"] || undefined;
export const ClickHouseIsHostHttps = process.env["CLICKHOUSE_IS_HOST_HTTPS"] === "true";
export const ShouldClickhouseSslEnable = Boolean(ClickhouseTlsCa || (ClickhouseTlsCert && ClickhouseTlsKey));
export const MaxClickhouseConnections = parseInt(process.env["CLICKHOUSE_MAX_OPEN_CONNECTIONS"] || "100", 10);
/*
 * Ingest pool size. Falls back to MaxClickhouseConnections so single-knob
 * setups still work; override only when the ingest pool needs to be sized
 * independently from the query pool.
 */
export const MaxClickhouseIngestConnections = parseInt(process.env["CLICKHOUSE_INGEST_MAX_OPEN_CONNECTIONS"] ||
    String(MaxClickhouseConnections), 10);
export const GitSha = process.env["GIT_SHA"] || "unknown";
export const AppVersion = process.env["APP_VERSION"] || "unknown";
export const LogLevel = process.env["LOG_LEVEL"] || ConfigLogLevel.INFO;
export const HttpProtocol = process.env["HTTP_PROTOCOL"] === "https" ? Protocol.HTTPS : Protocol.HTTP;
export const Host = process.env["HOST"] || "";
export const ProvisionSsl = process.env["PROVISION_SSL"] === "true";
export const CaptchaEnabled = process.env["CAPTCHA_ENABLED"] === "true";
export const CaptchaSecretKey = process.env["CAPTCHA_SECRET_KEY"] || "";
export const CaptchaSiteKey = process.env["CAPTCHA_SITE_KEY"] || "";
export const WorkflowScriptTimeoutInMS = process.env["WORKFLOW_SCRIPT_TIMEOUT_IN_MS"]
    ? parseInt(process.env["WORKFLOW_SCRIPT_TIMEOUT_IN_MS"].toString())
    : 5000;
export const WorkflowTimeoutInMs = process.env["WORKFLOW_TIMEOUT_IN_MS"]
    ? parseInt(process.env["WORKFLOW_TIMEOUT_IN_MS"].toString())
    : 5000;
export const AllowedActiveMonitorCountInFreePlan = process.env["ALLOWED_ACTIVE_MONITOR_COUNT_IN_FREE_PLAN"]
    ? parseInt(process.env["ALLOWED_ACTIVE_MONITOR_COUNT_IN_FREE_PLAN"].toString())
    : 10;
export const AllowedStatusPageCountInFreePlan = process.env["ALLOWED_STATUS_PAGE_COUNT_IN_FREE_PLAN"]
    ? parseInt(process.env["ALLOWED_STATUS_PAGE_COUNT_IN_FREE_PLAN"].toString())
    : 1;
export const AllowedSubscribersCountInFreePlan = process.env["ALLOWED_SUBSCRIBERS_COUNT_IN_FREE_PLAN"]
    ? parseInt(process.env["ALLOWED_SUBSCRIBERS_COUNT_IN_FREE_PLAN"].toString())
    : 100;
export const NotificationSlackWebhookOnCreateUser = process.env["NOTIFICATION_SLACK_WEBHOOK_ON_CREATED_USER"] || "";
export const NotificationSlackWebhookOnCreateProject = process.env["NOTIFICATION_SLACK_WEBHOOK_ON_CREATED_PROJECT"] || "";
// notification delete project
export const NotificationSlackWebhookOnDeleteProject = process.env["NOTIFICATION_SLACK_WEBHOOK_ON_DELETED_PROJECT"] || "";
// notification subscripton update.
export const NotificationSlackWebhookOnSubscriptionUpdate = process.env["NOTIFICATION_SLACK_WEBHOOK_ON_SUBSCRIPTION_UPDATE"] || "";
export const AdminDashboardClientURL = new URL(HttpProtocol, Host, new Route(AdminDashboardRoute.toString()));
export const AppApiClientUrl = new URL(HttpProtocol, Host, new Route(AppApiRoute.toString()));
export const StatusPageApiClientUrl = new URL(HttpProtocol, Host, new Route(StatusPageApiRoute.toString()));
/*
 *Internal URL for server-to-server communication (uses internal Docker hostname)
 *Note: The internal path is /api/status-page (not /status-page-api) because
 * /status-page-api is the external route that Nginx rewrites to /api/status-page
 */
export const StatusPageApiInternalUrl = URL.fromString(AppApiClientUrl.toString()).addRoute(new Route("/status-page"));
export const DashboardClientUrl = new URL(HttpProtocol, Host, new Route(DashboardRoute.toString()));
export const AccountsClientUrl = new URL(HttpProtocol, Host, new Route(AccountsRoute.toString()));
export const HomeClientUrl = new URL(HttpProtocol, Host, new Route(HomeRoute.toString()));
export const DocsClientUrl = new URL(HttpProtocol, Host, new Route(DocsRoute.toString()));
export const IpWhitelist = process.env["IP_WHITELIST"] || "";
export const DisableTelemetry = process.env["DISABLE_TELEMETRY"] === "true";
export const EnableProfiling = process.env["ENABLE_PROFILING"] === "true";
export const IsEnterpriseEdition = process.env["IS_ENTERPRISE_EDITION"] === "true";
export const AverageSpanRowSizeInBytes = parsePositiveNumberFromEnv("AVERAGE_SPAN_ROW_SIZE_IN_BYTES", 1024);
export const AverageLogRowSizeInBytes = parsePositiveNumberFromEnv("AVERAGE_LOG_ROW_SIZE_IN_BYTES", 1024);
export const AverageMetricRowSizeInBytes = parsePositiveNumberFromEnv("AVERAGE_METRIC_ROW_SIZE_IN_BYTES", 1024);
export const AverageExceptionRowSizeInBytes = parsePositiveNumberFromEnv("AVERAGE_EXCEPTION_ROW_SIZE_IN_BYTES", 1024);
export const AverageProfileRowSizeInBytes = parsePositiveNumberFromEnv("AVERAGE_PROFILE_ROW_SIZE_IN_BYTES", 1024);
export const AverageProfileSampleRowSizeInBytes = parsePositiveNumberFromEnv("AVERAGE_PROFILE_SAMPLE_ROW_SIZE_IN_BYTES", 512);
export const SlackAppClientId = process.env["SLACK_APP_CLIENT_ID"] || null;
export const SlackAppClientSecret = process.env["SLACK_APP_CLIENT_SECRET"] || null;
export const SlackAppSigningSecret = process.env["SLACK_APP_SIGNING_SECRET"] || null;
// Microsoft Teams Configuration
export const MicrosoftTeamsAppClientId = process.env["MICROSOFT_TEAMS_APP_CLIENT_ID"] || null;
export const MicrosoftTeamsAppClientSecret = process.env["MICROSOFT_TEAMS_APP_CLIENT_SECRET"] || null;
export const MicrosoftTeamsAppTenantId = process.env["MICROSOFT_TEAMS_APP_TENANT_ID"] || null;
// GitHub App Configuration
export const GitHubAppId = process.env["GITHUB_APP_ID"] || null;
export const GitHubAppName = process.env["GITHUB_APP_NAME"] || null;
export const GitHubAppClientId = process.env["GITHUB_APP_CLIENT_ID"] || null;
export const GitHubAppClientSecret = process.env["GITHUB_APP_CLIENT_SECRET"] || null;
// Helper function to decode base64 private key if needed
const decodePrivateKey = (key) => {
    if (!key) {
        return null;
    }
    // If it starts with "-----BEGIN", it's already in PEM format
    if (key.trim().startsWith("-----BEGIN")) {
        return key;
    }
    // Otherwise, assume it's base64 encoded and decode it
    try {
        const decoded = Buffer.from(key, "base64").toString("utf-8");
        // Verify it's a valid PEM key after decoding
        if (decoded.trim().startsWith("-----BEGIN")) {
            return decoded;
        }
        // If decoding doesn't produce a valid PEM, return original value
        return key;
    }
    catch (_a) {
        // If decoding fails, return the original value
        return key;
    }
};
export const GitHubAppPrivateKey = decodePrivateKey(process.env["GITHUB_APP_PRIVATE_KEY"]);
export const GitHubAppWebhookSecret = process.env["GITHUB_APP_WEBHOOK_SECRET"] || null;
// VAPID Configuration for Web Push Notifications
export const VapidPublicKey = process.env["VAPID_PUBLIC_KEY"] || undefined;
export const VapidPrivateKey = process.env["VAPID_PRIVATE_KEY"] || undefined;
export const VapidSubject = process.env["VAPID_SUBJECT"] || "mailto:support@oneuptime.com";
export const ExpoAccessToken = process.env["EXPO_ACCESS_TOKEN"] || undefined;
export const PushNotificationRelayUrl = process.env["PUSH_NOTIFICATION_RELAY_URL"] ||
    "https://oneuptime.com/api/notification/push-relay/send";
export const EnterpriseLicenseValidationUrl = URL.fromString("https://oneuptime.com/api/enterprise-license/validate");
export const EnterpriseLicenseUserCountReportUrl = URL.fromString("https://oneuptime.com/api/enterprise-license/report-user-count");
// Inbound Email Configuration for Incoming Email Monitor
export var InboundEmailProviderType;
(function (InboundEmailProviderType) {
    InboundEmailProviderType["SendGrid"] = "SendGrid";
})(InboundEmailProviderType || (InboundEmailProviderType = {}));
export const InboundEmailProvider = process.env["INBOUND_EMAIL_PROVIDER"] ||
    InboundEmailProviderType.SendGrid;
export const InboundEmailDomain = process.env["INBOUND_EMAIL_DOMAIN"] || undefined;
export const InboundEmailWebhookSecret = process.env["INBOUND_EMAIL_WEBHOOK_SECRET"] || undefined;
//# sourceMappingURL=EnvironmentConfig.js.map