/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.texera.amber.config

// Environment variable names for all the *.conf files
// TODO: currently these values are hard-coded, it would be good to have a way to dynamically load these names to avoid 2-copy
object EnvironmentalVariable {

  // utility function to load the env var
  def get(name: String): Option[String] = {
    Option(System.getenv(name))
  }

  /**
    * JVM related opts
    */
  val ENV_JAVA_OPTS = "JAVA_OPTS"

  /**
    * FileService related endpoint
    */
  val ENV_FILE_SERVICE_GET_PRESIGNED_URL_ENDPOINT = "FILE_SERVICE_GET_PRESIGNED_URL_ENDPOINT"
  val ENV_FILE_SERVICE_UPLOAD_ONE_FILE_TO_DATASET_ENDPOINT =
    "FILE_SERVICE_UPLOAD_ONE_FILE_TO_DATASET_ENDPOINT"

  /**
    * Auth related vars
    */
  val ENV_USER_JWT_TOKEN = "USER_JWT_TOKEN"
  val ENV_AUTH_JWT_SECRET = "AUTH_JWT_SECRET"

  // JDBC
  val ENV_JDBC_URL = "STORAGE_JDBC_URL"
  val ENV_JDBC_USERNAME = "STORAGE_JDBC_USERNAME"
  val ENV_JDBC_PASSWORD = "STORAGE_JDBC_PASSWORD"

  // Iceberg Catalog
  val ENV_ICEBERG_CATALOG_TYPE = "STORAGE_ICEBERG_CATALOG_TYPE"
  val ENV_ICEBERG_CATALOG_REST_URI = "STORAGE_ICEBERG_CATALOG_REST_URI"
  val ENV_ICEBERG_CATALOG_REST_WAREHOUSE_NAME = "STORAGE_ICEBERG_CATALOG_REST_WAREHOUSE_NAME"

  // Iceberg Postgres Catalog
  val ENV_ICEBERG_CATALOG_POSTGRES_URI_WITHOUT_SCHEME =
    "STORAGE_ICEBERG_CATALOG_POSTGRES_URI_WITHOUT_SCHEME"
  val ENV_ICEBERG_CATALOG_POSTGRES_USERNAME = "STORAGE_ICEBERG_CATALOG_POSTGRES_USERNAME"
  val ENV_ICEBERG_CATALOG_POSTGRES_PASSWORD = "STORAGE_ICEBERG_CATALOG_POSTGRES_PASSWORD"

  // Iceberg Table
  val ENV_ICEBERG_TABLE_RESULT_NAMESPACE = "STORAGE_ICEBERG_TABLE_RESULT_NAMESPACE"
  val ENV_ICEBERG_TABLE_CONSOLE_MESSAGES_NAMESPACE =
    "STORAGE_ICEBERG_TABLE_CONSOLE_MESSAGES_NAMESPACE"
  val ENV_ICEBERG_TABLE_RUNTIME_STATISTICS_NAMESPACE =
    "STORAGE_ICEBERG_TABLE_RUNTIME_STATISTICS_NAMESPACE"
  val ENV_ICEBERG_TABLE_COMMIT_BATCH_SIZE = "STORAGE_ICEBERG_TABLE_COMMIT_BATCH_SIZE"
  val ENV_ICEBERG_TABLE_COMMIT_NUM_RETRIES = "STORAGE_ICEBERG_TABLE_COMMIT_NUM_RETRIES"
  val ENV_ICEBERG_TABLE_COMMIT_MIN_WAIT_MS = "STORAGE_ICEBERG_TABLE_COMMIT_MIN_WAIT_MS"
  val ENV_ICEBERG_TABLE_COMMIT_MAX_WAIT_MS = "STORAGE_ICEBERG_TABLE_COMMIT_MAX_WAIT_MS"

  // LakeFS
  val ENV_LAKEFS_ENDPOINT = "STORAGE_LAKEFS_ENDPOINT"
  val ENV_LAKEFS_AUTH_API_SECRET = "STORAGE_LAKEFS_AUTH_API_SECRET"
  val ENV_LAKEFS_AUTH_USERNAME = "STORAGE_LAKEFS_AUTH_USERNAME"
  val ENV_LAKEFS_AUTH_PASSWORD = "STORAGE_LAKEFS_AUTH_PASSWORD"
  val ENV_LAKEFS_BLOCK_STORAGE_TYPE = "STORAGE_LAKEFS_BLOCK_STORAGE_TYPE"
  val ENV_LAKEFS_BLOCK_STORAGE_BUCKET_NAME = "STORAGE_LAKEFS_BLOCK_STORAGE_BUCKET_NAME"

  // S3
  val ENV_S3_ENDPOINT = "STORAGE_S3_ENDPOINT"
  val ENV_S3_REGION = "STORAGE_S3_REGION"
  val ENV_S3_AUTH_USERNAME = "STORAGE_S3_AUTH_USERNAME"
  val ENV_S3_AUTH_PASSWORD = "STORAGE_S3_AUTH_PASSWORD"

  /**
    * Variables in application.conf
    */
  // Constants
  val ENV_CONSTANTS_LOGGING_QUEUE_SIZE_INTERVAL = "CONSTANTS_LOGGING_QUEUE_SIZE_INTERVAL"
  val ENV_CONSTANTS_NUM_WORKER_PER_OPERATOR = "CONSTANTS_NUM_WORKER_PER_OPERATOR"
  val ENV_CONSTANTS_MAX_RESOLUTION_ROWS = "CONSTANTS_MAX_RESOLUTION_ROWS"
  val ENV_CONSTANTS_MAX_RESOLUTION_COLUMNS = "CONSTANTS_MAX_RESOLUTION_COLUMNS"
  val ENV_CONSTANTS_STATUS_UPDATE_INTERVAL = "CONSTANTS_STATUS_UPDATE_INTERVAL"

  // Flow Control
  val ENV_FLOW_CONTROL_MAX_CREDIT_ALLOWED_IN_BYTES_PER_CHANNEL =
    "FLOW_CONTROL_MAX_CREDIT_ALLOWED_IN_BYTES_PER_CHANNEL"
  val ENV_FLOW_CONTROL_CREDIT_POLL_INTERVAL_IN_MS = "FLOW_CONTROL_CREDIT_POLL_INTERVAL_IN_MS"

  // Network Buffering
  val ENV_NETWORK_BUFFERING_DEFAULT_DATA_TRANSFER_BATCH_SIZE =
    "NETWORK_BUFFERING_DEFAULT_DATA_TRANSFER_BATCH_SIZE"
  val ENV_NETWORK_BUFFERING_ENABLE_ADAPTIVE_BUFFERING =
    "NETWORK_BUFFERING_ENABLE_ADAPTIVE_BUFFERING"
  val ENV_NETWORK_BUFFERING_ADAPTIVE_BUFFERING_TIMEOUT_MS =
    "NETWORK_BUFFERING_ADAPTIVE_BUFFERING_TIMEOUT_MS"

  // Reconfiguration
  val ENV_RECONFIGURATION_ENABLE_TRANSACTIONAL_RECONFIGURATION =
    "RECONFIGURATION_ENABLE_TRANSACTIONAL_RECONFIGURATION"

  // Cache
  val ENV_CACHE_ENABLED = "CACHE_ENABLED"

  // User System
  val ENV_USER_SYS_ENABLED = "USER_SYS_ENABLED"
  val ENV_USER_SYS_GOOGLE_CLIENT_ID = "USER_SYS_GOOGLE_CLIENT_ID"
  val ENV_USER_SYS_GOOGLE_SMTP_GMAIL = "USER_SYS_GOOGLE_SMTP_GMAIL"
  val ENV_USER_SYS_GOOGLE_SMTP_PASSWORD = "USER_SYS_GOOGLE_SMTP_PASSWORD"
  val ENV_USER_SYS_VERSION_TIME_LIMIT_IN_MINUTES = "USER_SYS_VERSION_TIME_LIMIT_IN_MINUTES"

  // Result Cleanup
  val ENV_RESULT_CLEANUP_TTL_IN_SECONDS = "RESULT_CLEANUP_TTL_IN_SECONDS"
  val ENV_RESULT_CLEANUP_COLLECTION_CHECK_INTERVAL_IN_SECONDS =
    "RESULT_CLEANUP_COLLECTION_CHECK_INTERVAL_IN_SECONDS"

  // Web Server
  val ENV_WEB_SERVER_WORKFLOW_STATE_CLEANUP_IN_SECONDS =
    "WEB_SERVER_WORKFLOW_STATE_CLEANUP_IN_SECONDS"
  val ENV_WEB_SERVER_PYTHON_CONSOLE_BUFFER_SIZE = "WEB_SERVER_PYTHON_CONSOLE_BUFFER_SIZE"
  val ENV_WEB_SERVER_WORKFLOW_RESULT_PULLING_IN_SECONDS =
    "WEB_SERVER_WORKFLOW_RESULT_PULLING_IN_SECONDS"
  val ENV_WEB_SERVER_CLEAN_ALL_EXECUTION_RESULTS_ON_SERVER_START =
    "WEB_SERVER_CLEAN_ALL_EXECUTION_RESULTS_ON_SERVER_START"
  val ENV_MAX_WORKFLOW_WEBSOCKET_REQUEST_PAYLOAD_SIZE_KB =
    "MAX_WORKFLOW_WEBSOCKET_REQUEST_PAYLOAD_SIZE_KB"

  // Fault Tolerance
  val ENV_FAULT_TOLERANCE_LOG_STORAGE_URI = "FAULT_TOLERANCE_LOG_STORAGE_URI"
  val ENV_FAULT_TOLERANCE_LOG_FLUSH_INTERVAL_MS = "FAULT_TOLERANCE_LOG_FLUSH_INTERVAL_MS"
  val ENV_FAULT_TOLERANCE_LOG_RECORD_MAX_SIZE_IN_BYTE =
    "FAULT_TOLERANCE_LOG_RECORD_MAX_SIZE_IN_BYTE"
  val ENV_FAULT_TOLERANCE_MAX_SUPPORTED_RESEND_QUEUE_LENGTH =
    "FAULT_TOLERANCE_MAX_SUPPORTED_RESEND_QUEUE_LENGTH"
  val ENV_FAULT_TOLERANCE_DELAY_BEFORE_RECOVERY = "FAULT_TOLERANCE_DELAY_BEFORE_RECOVERY"
  val ENV_FAULT_TOLERANCE_HDFS_STORAGE_ADDRESS = "FAULT_TOLERANCE_HDFS_STORAGE_ADDRESS"

  // Schedule Generator
  val ENV_SCHEDULE_GENERATOR_ENABLE_COST_BASED_SCHEDULE_GENERATOR =
    "SCHEDULE_GENERATOR_ENABLE_COST_BASED_SCHEDULE_GENERATOR"
  val ENV_SCHEDULE_GENERATOR_MAX_CONCURRENT_REGIONS = "SCHEDULE_GENERATOR_MAX_CONCURRENT_REGIONS"
  val ENV_SCHEDULE_GENERATOR_USE_GLOBAL_SEARCH = "SCHEDULE_GENERATOR_USE_GLOBAL_SEARCH"
  val ENV_SCHEDULE_GENERATOR_USE_TOP_DOWN_SEARCH = "SCHEDULE_GENERATOR_USE_TOP_DOWN_SEARCH"
  val ENV_SCHEDULE_GENERATOR_SEARCH_TIMEOUT_MILLISECONDS =
    "SCHEDULE_GENERATOR_SEARCH_TIMEOUT_MILLISECONDS"

  // AI Assistant Server
  val ENV_AI_ASSISTANT_SERVER_ASSISTANT = "AI_ASSISTANT_SERVER_ASSISTANT"
  val ENV_AI_ASSISTANT_SERVER_AI_SERVICE_KEY = "AI_ASSISTANT_SERVER_AI_SERVICE_KEY"
  val ENV_AI_ASSISTANT_SERVER_AI_SERVICE_URL = "AI_ASSISTANT_SERVER_AI_SERVICE_URL"
}
