package storage

import (
	"os"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/observability/vmbackupmanager/pkg/config"
)

func TestGetS3Client(t *testing.T) {
	tests := []struct {
		name        string
		storageType StorageType
		envVars     map[string]string
		expectError bool
		errorSubstr string
	}{
		{
			name:        "Unsupported storage type",
			storageType: "unsupported",
			expectError: true,
			errorSubstr: "not supported provider",
		},
		{
			name:        "Azure storage without account name",
			storageType: StorageTypeAzure,
			envVars:     map[string]string{},
			expectError: true,
			errorSubstr: "azure storage account is not set",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Save old environment
			oldEnv := make(map[string]string)
			for k := range tt.envVars {
				oldEnv[k] = os.Getenv(k)
			}
			oldAcctName := os.Getenv(envStorageAcctName)

			// Set test environment
			for k, v := range tt.envVars {
				os.Setenv(k, v)
			}

			// Clean up environment after test
			defer func() {
				for k, v := range oldEnv {
					os.Setenv(k, v)
				}
				os.Setenv(envStorageAcctName, oldAcctName)
			}()

			// Call the function under test
			cfg := &config.Config{
				Destination: "s3://bucket/path",
			}
			client, err := getS3Client(tt.storageType, cfg)

			// Verify expectations
			if tt.expectError {
				assert.Error(t, err)
				if tt.errorSubstr != "" {
					assert.Contains(t, err.Error(), tt.errorSubstr)
				}
				assert.Nil(t, client)
			} else {
				assert.NoError(t, err)
				assert.NotNil(t, client)
			}
		})
	}
}

// TestNewS3StorageWithFSPath tests that filesystem paths still work correctly
func TestNewS3StorageWithFSPath(t *testing.T) {
	// Set up temporary directory
	tempDir, err := os.MkdirTemp("", "storage-test")
	if err != nil {
		t.Fatalf("Failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(tempDir)

	// Create filesystem storage
	storagePath := "fs://" + tempDir
	cfg := &config.Config{
		Destination: storagePath,
	}
	storage, err := NewStorage(cfg)

	// Verify it works
	assert.NoError(t, err)
	assert.NotNil(t, storage)
}
