package storage

import "testing"

func clearStorageEnv(t *testing.T) {
	t.Helper()

	for _, name := range []string{
		"FILE_STORAGE_PROVIDER",
		"FILE_STORAGE_ROOT",
		"FILE_STORAGE_LEGACY_UPLOAD_ROOT",
		"FILE_STORAGE_BUCKET",
		"FILE_STORAGE_REGION",
		"FILE_STORAGE_ENDPOINT",
		"FILE_STORAGE_ACCESS_KEY_ID",
		"FILE_STORAGE_SECRET_ACCESS_KEY",
		"FILE_STORAGE_SESSION_TOKEN",
		"FILE_STORAGE_PREFIX",
		"FILE_STORAGE_USE_PATH_STYLE",
		"AWS_ACCESS_KEY_ID",
		"AWS_SECRET_ACCESS_KEY",
		"AWS_PROFILE",
	} {
		t.Setenv(name, "")
	}
}

func TestLoadConfigFromEnvS3(t *testing.T) {
	t.Setenv("FILE_STORAGE_PROVIDER", "s3")
	t.Setenv("FILE_STORAGE_BUCKET", "bucket-1")
	t.Setenv("FILE_STORAGE_REGION", "us-west-2")
	t.Setenv("FILE_STORAGE_ENDPOINT", "http://localhost:9000")
	t.Setenv("FILE_STORAGE_ACCESS_KEY_ID", "access")
	t.Setenv("FILE_STORAGE_SECRET_ACCESS_KEY", "secret")
	t.Setenv("FILE_STORAGE_SESSION_TOKEN", "token")
	t.Setenv("FILE_STORAGE_PREFIX", "tenant-a")
	t.Setenv("FILE_STORAGE_USE_PATH_STYLE", "true")

	cfg := LoadConfigFromEnv()
	if cfg.Provider != ProviderS3 {
		t.Fatalf("Provider = %q, want %q", cfg.Provider, ProviderS3)
	}
	if cfg.Bucket != "bucket-1" {
		t.Fatalf("Bucket = %q", cfg.Bucket)
	}
	if cfg.Region != "us-west-2" {
		t.Fatalf("Region = %q", cfg.Region)
	}
	if cfg.Endpoint != "http://localhost:9000" {
		t.Fatalf("Endpoint = %q", cfg.Endpoint)
	}
	if cfg.AccessKeyID != "access" || cfg.SecretAccessKey != "secret" || cfg.SessionToken != "token" {
		t.Fatalf("credentials not loaded correctly")
	}
	if cfg.KeyPrefix != "tenant-a" {
		t.Fatalf("KeyPrefix = %q", cfg.KeyPrefix)
	}
	if !cfg.UsePathStyle {
		t.Fatalf("UsePathStyle should be true")
	}
}

func TestNewStoreSupportsS3(t *testing.T) {
	t.Setenv("AWS_EC2_METADATA_DISABLED", "true")

	store, err := NewStore(Config{
		Provider:        ProviderS3,
		Bucket:          "bucket-1",
		Region:          "us-east-1",
		Endpoint:        "http://localhost:9000",
		AccessKeyID:     "access",
		SecretAccessKey: "secret",
		UsePathStyle:    true,
	})
	if err != nil {
		t.Fatalf("NewStore() error = %v", err)
	}
	if _, ok := store.(*S3Store); !ok {
		t.Fatalf("NewStore() type = %T, want *S3Store", store)
	}
}

func TestLoadConfigFromEnvDefaultsToFilesystemWithoutS3Hints(t *testing.T) {
	clearStorageEnv(t)

	cfg := LoadConfigFromEnv()
	if cfg.Provider != ProviderFilesystem {
		t.Fatalf("Provider = %q, want %q", cfg.Provider, ProviderFilesystem)
	}
	if cfg.FilesystemRoot != "data/object-storage" {
		t.Fatalf("FilesystemRoot = %q", cfg.FilesystemRoot)
	}
	if cfg.LegacyUploadRoot != "data/uploads" {
		t.Fatalf("LegacyUploadRoot = %q", cfg.LegacyUploadRoot)
	}
}

func TestLoadConfigFromEnvInfersS3WhenProviderUnsetButRuntimeHintsExist(t *testing.T) {
	t.Setenv("FILE_STORAGE_BUCKET", "bucket-2")
	t.Setenv("FILE_STORAGE_ENDPOINT", "http://localhost:9000")

	cfg := LoadConfigFromEnv()
	if cfg.Provider != ProviderS3 {
		t.Fatalf("Provider = %q, want %q", cfg.Provider, ProviderS3)
	}
}
