package config

import (
	"fmt"
	"os"
	"strconv"
	"time"
)

// DataDir is the base directory for all runtime files
var DataDir string

// StorageType controls task metadata backend: mysql, tidb or memory.
var StorageType string

// MySQLDSN is the DSN used by mysql protocol compatible storage backend.
// It prefers MYSQL_DSN and falls back to legacy TIDB_DSN for compatibility.
var MySQLDSN string

// MaxRetries controls task retry attempts
var MaxRetries int

// MaxConcurrentTasks controls worker concurrency
var MaxConcurrentTasks int

// TaskPollInterval controls worker polling interval
var TaskPollInterval time.Duration
var StaleTaskTTL time.Duration
var DumplingTimeout time.Duration
var LightningTimeout time.Duration

// Lightning tuning knobs
var LightningTableConcurrency int
var LightningIndexConcurrency int
var LightningRegionConcurrency int
var LightningIOConcurrency int
var LightningBatchSize int
var LightningBatchRows int

// EnablePostImportVerification controls expensive post import schema scan
var EnablePostImportVerification bool

// InitConfig initializes the configuration
func InitConfig() {
	// Get data directory from environment variable
	dataDir := os.Getenv("DATA_DIR")
	if dataDir == "" {
		dataDir = "./data"
	}
	DataDir = dataDir

	StorageType = getEnvOrDefault("STORAGE_TYPE", "memory")
	MySQLDSN = os.Getenv("MYSQL_DSN")
	if MySQLDSN == "" {
		MySQLDSN = os.Getenv("TIDB_DSN")
	}
	MaxRetries = getIntEnvOrDefault("MAX_RETRIES", 3)
	MaxConcurrentTasks = getIntEnvOrDefault("MAX_CONCURRENT_TASKS", 3)
	pollMs := getIntEnvOrDefault("TASK_POLL_INTERVAL_MS", 500)
	TaskPollInterval = time.Duration(pollMs) * time.Millisecond
	staleTTLSeconds := getIntEnvOrDefault("STALE_TASK_TTL_SECONDS", 900)
	StaleTaskTTL = time.Duration(staleTTLSeconds) * time.Second
	dumplingTimeoutSeconds := getIntEnvOrDefault("DUMPLING_TIMEOUT_SECONDS", 300)
	DumplingTimeout = time.Duration(dumplingTimeoutSeconds) * time.Second
	lightningTimeoutSeconds := getIntEnvOrDefault("LIGHTNING_TIMEOUT_SECONDS", 900)
	LightningTimeout = time.Duration(lightningTimeoutSeconds) * time.Second

	LightningTableConcurrency = getIntEnvOrDefault("LIGHTNING_TABLE_CONCURRENCY", 16)
	LightningIndexConcurrency = getIntEnvOrDefault("LIGHTNING_INDEX_CONCURRENCY", 16)
	LightningRegionConcurrency = getIntEnvOrDefault("LIGHTNING_REGION_CONCURRENCY", 16)
	LightningIOConcurrency = getIntEnvOrDefault("LIGHTNING_IO_CONCURRENCY", 8)
	LightningBatchSize = getIntEnvOrDefault("LIGHTNING_BATCH_SIZE", 65536)
	LightningBatchRows = getIntEnvOrDefault("LIGHTNING_BATCH_ROWS", 32768)

	EnablePostImportVerification = getBoolEnvOrDefault("ENABLE_POST_IMPORT_VERIFICATION", false)
}

func getEnvOrDefault(key, fallback string) string {
	if value := os.Getenv(key); value != "" {
		return value
	}
	return fallback
}

func getIntEnvOrDefault(key string, fallback int) int {
	value := os.Getenv(key)
	if value == "" {
		return fallback
	}
	parsed, err := strconv.Atoi(value)
	if err != nil {
		fmt.Printf("invalid value for %s=%q, fallback to %d\n", key, value, fallback)
		return fallback
	}
	return parsed
}

func getBoolEnvOrDefault(key string, fallback bool) bool {
	value := os.Getenv(key)
	if value == "" {
		return fallback
	}
	parsed, err := strconv.ParseBool(value)
	if err != nil {
		fmt.Printf("invalid value for %s=%q, fallback to %t\n", key, value, fallback)
		return fallback
	}
	return parsed
}
