package framework

import (
	"os"
	"time"

	"gopkg.in/yaml.v3"
)

type Config struct {
	// O11yGSURL observability global server URL
	O11yGSURL string `yaml:"o11yGSURL"`

	// O11yGatewayURL observability gateway URL (for new path testing)
	O11yGatewayURL string `yaml:"o11yGatewayURL"`

	// ClinicURL clinic server URL (for keyvisual, etc.)
	ClinicURL string `yaml:"clinicURL"`

	// MetricsURL metrics server URL (for shared cluster old path metrics query)
	MetricsURL string `yaml:"metricsURL"`

	// OrgID  (tenantID)
	OrgID string `yaml:"orgID"`

	// ProjectID
	ProjectID string `yaml:"projectID"`

	// RegionID  (x-region-id)
	RegionID string `yaml:"regionID"`

	// Origin
	Origin string `yaml:"origin"`

	// BizType
	BizType string `yaml:"bizType"`

	// Timeout HTTP
	Timeout time.Duration `yaml:"timeout"`

	// RetryCount
	RetryCount int `yaml:"retryCount"`

	// RetryDelay
	RetryDelay time.Duration `yaml:"retryDelay"`

	// OutputFile
	OutputFile string `yaml:"outputFile"`

	// Verbose
	Verbose bool `yaml:"verbose"`

	// Headers
	Headers map[string]string `yaml:"headers"`

	// EnableNewPath enables testing with new API path for dedicated clusters
	// When enabled, tests will run both old and new paths for o11yGSURL APIs
	EnableNewPath bool `yaml:"enableNewPath"`
}

// DefaultConfig
func DefaultConfig() *Config {
	return &Config{
		O11yGSURL:      "https://api.tidbcloud.com",
		O11yGatewayURL: "",
		ClinicURL:      "",
		OrgID:          "",
		ProjectID:      "",
		RegionID:       "",
		Origin:         "https://tidbcloud.com",
		BizType:        "tidbcloud",
		Timeout:        30 * time.Second,
		RetryCount:     0,
		RetryDelay:     2 * time.Second,
		OutputFile:     "",
		Verbose:        false,
		Headers:        make(map[string]string),
		EnableNewPath:  false,
	}
}

// LoadConfig
func LoadConfig(path string) (*Config, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}

	config := DefaultConfig()
	if err := yaml.Unmarshal(data, config); err != nil {
		return nil, err
	}

	return config, nil
}

// LoadConfigOrDefault
func LoadConfigOrDefault(path string) *Config {
	if path == "" {
		return DefaultConfig()
	}

	config, err := LoadConfig(path)
	if err != nil {
		return DefaultConfig()
	}

	return config
}

// Validate
func (c *Config) Validate() error {
	if c.Timeout <= 0 {
		c.Timeout = 30 * time.Second
	}
	if c.RetryCount < 0 {
		c.RetryCount = 0
	}
	if c.RetryDelay <= 0 {
		c.RetryDelay = 2 * time.Second
	}
	return nil
}
