package storage

import (
	"path/filepath"
	"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",
		"NEXUSCRM_RUNTIME_ROOT",
		"AWS_ACCESS_KEY_ID",
		"AWS_SECRET_ACCESS_KEY",
		"AWS_PROFILE",
	} {
		t.Setenv(name, "")
	}
}

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

	cfg := LoadConfigFromEnv()

	if cfg.Provider != ProviderFilesystem {
		t.Fatalf("Provider = %q; want %q", cfg.Provider, ProviderFilesystem)
	}
	if cfg.Bucket != DefaultFilesystemBucket {
		t.Fatalf("Bucket = %q; want %q", cfg.Bucket, DefaultFilesystemBucket)
	}
	repoRoot := runtimeBaseDir()
	if cfg.FilesystemRoot != filepath.Join(repoRoot, DefaultFilesystemRoot) {
		t.Fatalf("FilesystemRoot = %q; want repo-root anchored default", cfg.FilesystemRoot)
	}
	if cfg.LegacyUploadRoot != filepath.Join(repoRoot, DefaultLegacyUploadRoot) {
		t.Fatalf("LegacyUploadRoot = %q; want repo-root anchored default", cfg.LegacyUploadRoot)
	}
}

func TestLoadConfigFromEnv_FilesystemBucketOverrideIsHonored(t *testing.T) {
	clearStorageEnv(t)
	t.Setenv("FILE_STORAGE_PROVIDER", ProviderFilesystem)
	t.Setenv("FILE_STORAGE_BUCKET", "tenant-local")

	cfg := LoadConfigFromEnv()

	if cfg.Bucket != "tenant-local" {
		t.Fatalf("Bucket = %q; want tenant-local", cfg.Bucket)
	}
}

func TestLoadConfigFromEnv_S3BucketRequiredByS3Store(t *testing.T) {
	clearStorageEnv(t)
	t.Setenv("FILE_STORAGE_PROVIDER", ProviderS3)

	cfg := LoadConfigFromEnv()

	if cfg.Provider != ProviderS3 {
		t.Fatalf("Provider = %q; want %q", cfg.Provider, ProviderS3)
	}
	if cfg.Bucket != "" {
		t.Fatalf("Bucket = %q; want empty so NewS3Store can fail loudly", cfg.Bucket)
	}
}

func TestLoadConfigFromEnv_RuntimeRootAnchorsRelativeStoragePaths(t *testing.T) {
	clearStorageEnv(t)
	root := t.TempDir()
	t.Setenv("NEXUSCRM_RUNTIME_ROOT", root)
	t.Setenv("FILE_STORAGE_ROOT", "files")
	t.Setenv("FILE_STORAGE_LEGACY_UPLOAD_ROOT", "uploads")

	cfg := LoadConfigFromEnv()

	if cfg.FilesystemRoot != filepath.Join(root, "files") {
		t.Fatalf("FilesystemRoot = %q; want runtime-root anchored path", cfg.FilesystemRoot)
	}
	if cfg.LegacyUploadRoot != filepath.Join(root, "uploads") {
		t.Fatalf("LegacyUploadRoot = %q; want runtime-root anchored path", cfg.LegacyUploadRoot)
	}
}

func TestLoadConfigFromEnv_SourceRepoRootIsStableAcrossChildCwd(t *testing.T) {
	clearStorageEnv(t)
	repoRoot := runtimeBaseDir()
	t.Chdir(filepath.Join(repoRoot, "backend"))

	cfg := LoadConfigFromEnv()

	if cfg.FilesystemRoot != filepath.Join(repoRoot, DefaultFilesystemRoot) {
		t.Fatalf("FilesystemRoot = %q; want repo-root anchored default", cfg.FilesystemRoot)
	}
	if cfg.LegacyUploadRoot != filepath.Join(repoRoot, DefaultLegacyUploadRoot) {
		t.Fatalf("LegacyUploadRoot = %q; want repo-root anchored default", cfg.LegacyUploadRoot)
	}
}

func TestLoadConfigFromEnv_AbsoluteStoragePathsRemainAbsolute(t *testing.T) {
	clearStorageEnv(t)
	filesRoot := filepath.Join(t.TempDir(), "files")
	uploadsRoot := filepath.Join(t.TempDir(), "uploads")
	t.Setenv("FILE_STORAGE_ROOT", filesRoot)
	t.Setenv("FILE_STORAGE_LEGACY_UPLOAD_ROOT", uploadsRoot)

	cfg := LoadConfigFromEnv()

	if cfg.FilesystemRoot != filesRoot {
		t.Fatalf("FilesystemRoot = %q; want %q", cfg.FilesystemRoot, filesRoot)
	}
	if cfg.LegacyUploadRoot != uploadsRoot {
		t.Fatalf("LegacyUploadRoot = %q; want %q", cfg.LegacyUploadRoot, uploadsRoot)
	}
}
