package cassandra

import (
	"time"

	"github.com/gocql/gocql"
)

// config 是初始化 DB 所需的內部設定（私有）
type config struct {
	Hosts                    []string          // Cassandra 主機列表
	Port                     int               // 連線埠
	Keyspace                 string            // 預設使用的 Keyspace
	Username                 string            // 認證用戶名
	Password                 string            // 認證密碼
	Consistency              gocql.Consistency // 一致性級別
	ConnectTimeoutSec        int               // 連線逾時秒數
	NumConns                 int               // 每個節點連線數
	MaxRetries               int               // 重試次數
	UseAuth                  bool              // 是否使用帳號密碼驗證
	RetryMinInterval         time.Duration     // 重試間隔最小值
	RetryMaxInterval         time.Duration     // 重試間隔最大值
	ReconnectInitialInterval time.Duration     // 重連初始間隔
	ReconnectMaxInterval     time.Duration     // 重連最大間隔
	CQLVersion               string            // 執行連線的CQL 版本號
}

// defaultConfig 返回預設配置
func defaultConfig() *config {
	return &config{
		Port:                     defaultPort,
		Consistency:              defaultConsistency,
		ConnectTimeoutSec:        defaultTimeoutSec,
		NumConns:                 defaultNumConns,
		MaxRetries:               defaultMaxRetries,
		RetryMinInterval:         defaultRetryMinInterval,
		RetryMaxInterval:         defaultRetryMaxInterval,
		ReconnectInitialInterval: defaultReconnectInitialInterval,
		ReconnectMaxInterval:     defaultReconnectMaxInterval,
		CQLVersion:               defaultCqlVersion,
	}
}

// Option 是設定選項的函數型別
type Option func(*config)

// WithHosts 設定 Cassandra 主機列表
func WithHosts(hosts ...string) Option {
	return func(c *config) {
		c.Hosts = hosts
	}
}

// WithPort 設定連線埠
func WithPort(port int) Option {
	return func(c *config) {
		c.Port = port
	}
}

// WithKeyspace 設定預設 keyspace
func WithKeyspace(keyspace string) Option {
	return func(c *config) {
		c.Keyspace = keyspace
	}
}

// WithAuth 設定認證資訊
func WithAuth(username, password string) Option {
	return func(c *config) {
		c.Username = username
		c.Password = password
		c.UseAuth = true
	}
}

// WithConsistency 設定一致性級別
func WithConsistency(consistency gocql.Consistency) Option {
	return func(c *config) {
		c.Consistency = consistency
	}
}

// WithConnectTimeoutSec 設定連線逾時秒數
func WithConnectTimeoutSec(timeout int) Option {
	return func(c *config) {
		if timeout <= 0 {
			timeout = defaultTimeoutSec
		}
		c.ConnectTimeoutSec = timeout
	}
}

// WithNumConns 設定每個節點的連線數
func WithNumConns(numConns int) Option {
	return func(c *config) {
		if numConns <= 0 {
			numConns = defaultNumConns
		}
		c.NumConns = numConns
	}
}

// WithMaxRetries 設定最大重試次數
func WithMaxRetries(maxRetries int) Option {
	return func(c *config) {
		if maxRetries <= 0 {
			maxRetries = defaultMaxRetries
		}
		c.MaxRetries = maxRetries
	}
}

// WithRetryMinInterval 設定最小重試間隔
func WithRetryMinInterval(duration time.Duration) Option {
	return func(c *config) {
		if duration <= 0 {
			duration = defaultRetryMinInterval
		}
		c.RetryMinInterval = duration
	}
}

// WithRetryMaxInterval 設定最大重試間隔
func WithRetryMaxInterval(duration time.Duration) Option {
	return func(c *config) {
		if duration <= 0 {
			duration = defaultRetryMaxInterval
		}
		c.RetryMaxInterval = duration
	}
}

// WithReconnectInitialInterval 設定初始重連間隔
func WithReconnectInitialInterval(duration time.Duration) Option {
	return func(c *config) {
		if duration <= 0 {
			duration = defaultReconnectInitialInterval
		}
		c.ReconnectInitialInterval = duration
	}
}

// WithReconnectMaxInterval 設定最大重連間隔
func WithReconnectMaxInterval(duration time.Duration) Option {
	return func(c *config) {
		if duration <= 0 {
			duration = defaultReconnectMaxInterval
		}
		c.ReconnectMaxInterval = duration
	}
}

// WithCQLVersion 設定 CQL 版本
func WithCQLVersion(version string) Option {
	return func(c *config) {
		if version == "" {
			version = defaultCqlVersion
		}
		c.CQLVersion = version
	}
}
