package config

import (
	"testing"
	"time"

	"github.com/tidbcloud/observability/pkg/common/constants"
)

func TestConfig_Validate(t *testing.T) {
	tests := []struct {
		name    string
		config  Config
		wantErr bool
		errMsg  string
	}{
		{
			name: "valid configuration",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1, // Ensured > 0
				FullBackupConcurrency: 1, // Ensured > 0
				IncrSchedule:          "10 * * * *",
				FullSchedule:          "0 0 1 * *",
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: false,
		},
		{
			name: "empty StorageDataPath",
			config: Config{
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1, // Ensured > 0
				FullBackupConcurrency: 1, // Ensured > 0
				IncrSchedule:          "10 * * * *",
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "storageDataPath cannot be empty",
		},
		{
			name: "empty Destination",
			config: Config{
				StorageDataPath:       "/data",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1, // Ensured > 0
				FullBackupConcurrency: 1, // Ensured > 0
				IncrSchedule:          "10 * * * *",
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "destination cannot be empty",
		},
		{
			name: "empty SnapshotCreateURL",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				Concurrency:           1, // Ensured > 0
				FullBackupConcurrency: 1, // Ensured > 0
				IncrSchedule:          "10 * * * *",
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "snapshot.createURL cannot be empty",
		},
		{
			name: "empty IncrSchedule",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1, // Ensured > 0
				FullBackupConcurrency: 1, // Ensured > 0
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "incrSchedule cannot be empty",
		},
		{
			name: "invalid IncrSchedule format",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1, // Ensured > 0
				FullBackupConcurrency: 1, // Ensured > 0
				IncrSchedule:          "invalid-cron-format",
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "invalid incrSchedule format: expected exactly 5 fields, found 1: [invalid-cron-format]",
		},
		{
			name: "invalid FullSchedule format",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1, // Ensured > 0
				FullBackupConcurrency: 1, // Ensured > 0
				IncrSchedule:          "10 * * * *",
				FullSchedule:          "invalid-cron-format",
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "invalid fullSchedule format: expected exactly 5 fields, found 1: [invalid-cron-format]",
		},
		{
			name: "empty FullSchedule is valid",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1, // Ensured > 0
				FullBackupConcurrency: 1, // Ensured > 0
				IncrSchedule:          "10 * * * *",
				FullSchedule:          "",
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: false,
		},
		{
			name: "zero Concurrency",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           0,
				FullBackupConcurrency: 1,
				IncrSchedule:          "10 * * * *",
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "concurrency must be greater than 0",
		},
		{
			name: "invalid Vendor",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1, // Ensured > 0
				FullBackupConcurrency: 1, // Ensured > 0
				IncrSchedule:          "10 * * * *",
				Vendor:                "invalid",
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "invalid vendor: invalid",
		},
		{
			name: "zero FullBackupConcurrency",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1,
				FullBackupConcurrency: 0,
				IncrSchedule:          "10 * * * *",
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "fullBackupConcurrency must be greater than 0",
		},
		{
			name: "negative BackupRetention",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1,
				FullBackupConcurrency: 1,
				IncrSchedule:          "10 * * * *",
				BackupRetention:       -1 * time.Hour,
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "backupRetention cannot be negative",
		},
		{
			name: "negative VMRetentionPeriod",
			config: Config{
				StorageDataPath:       "/data",
				Destination:           "s3://bucket/path",
				SnapshotCreateURL:     "http://example.com/snapshot",
				Concurrency:           1,
				FullBackupConcurrency: 1,
				IncrSchedule:          "10 * * * *",
				VMRetentionPeriod:     -1 * time.Hour,
				Vendor:                constants.AWS,
				Region:                "us-west-2",
			},
			wantErr: true,
			errMsg:  "vmRetentionPeriod cannot be negative",
		},
		{
			name: "valid with all fields populated",
			config: Config{
				StorageDataPath:           "/data",
				Destination:               "s3://bucket/path",
				SnapshotCreateURL:         "http://example.com/snapshot",
				Concurrency:               5,
				FullBackupConcurrency:     3,
				MaxBytesPerSecond:         "10MB",
				HttpListenAddr:            ":8080",
				IncrSchedule:              "10 * * * *",
				FullSchedule:              "0 0 * * 0",
				BackupRetention:           24 * time.Hour,
				VMRetentionPeriod:         48 * time.Hour,
				VMRetentionTimeZoneOffset: 8 * time.Hour,
				DisableFullBackup:         false,
				DisableBackupRetention:    false,
				Migrate:                   true,
				Vendor:                    constants.AWS,
				Region:                    "us-west-2",
			},
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			err := tt.config.Validate()
			if (err != nil) != tt.wantErr {
				t.Errorf("Config.Validate() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if err != nil && tt.errMsg != "" && err.Error() != tt.errMsg {
				t.Errorf("Config.Validate() error message = %v, expected %v", err.Error(), tt.errMsg)
			}
		})
	}
}
