package db

import (
	"os"
	"path/filepath"
	"runtime"
	"testing"
)

func TestPostgresRuntimeSupportRequiresInstallMarker(t *testing.T) {
	tmpDir := t.TempDir()
	SetExternalDriverDownloadDirectory(tmpDir)

	supported, _ := DriverRuntimeSupportStatus("postgres")
	if !supported {
		t.Fatalf("postgres 属于免安装内置驱动，应可用")
	}
	supported, reason := DriverRuntimeSupportStatus("postgres")
	if !supported {
		t.Fatalf("postgres 应可用，reason=%s", reason)
	}
}

func TestBuiltinLikeDriversRemainAvailable(t *testing.T) {
	tmpDir := t.TempDir()
	SetExternalDriverDownloadDirectory(tmpDir)

	supported, reason := DriverRuntimeSupportStatus("redis")
	if !supported {
		t.Fatalf("redis 应始终可用，reason=%s", reason)
	}
}

func TestOptionalDriverAgentRevisionsGeneratedForOptionalDrivers(t *testing.T) {
	for driverType := range optionalGoDrivers {
		revision := OptionalDriverAgentRevision(driverType)
		if revision == "" {
			t.Fatalf("%s 缺少自动生成的 driver-agent revision", driverType)
		}
		if revision == "src-local" {
			t.Fatalf("%s driver-agent revision 仍是本地占位值", driverType)
		}
	}
	if OptionalDriverAgentRevision("doris") != OptionalDriverAgentRevision("diros") {
		t.Fatalf("doris/diros revision 应归一一致")
	}
}

func TestKingbaseRuntimeAliasesNormalizeToKingbase(t *testing.T) {
	if got := normalizeRuntimeDriverType("kingbase8"); got != "kingbase" {
		t.Fatalf("expected kingbase8 runtime alias to normalize to kingbase, got %q", got)
	}
	if got := normalizeDatabaseType("kingbasees"); got != "kingbase" {
		t.Fatalf("expected kingbasees database alias to normalize to kingbase, got %q", got)
	}
}

func TestManagedDriverRequiresInstallMarker(t *testing.T) {
	tmpDir := t.TempDir()
	SetExternalDriverDownloadDirectory(tmpDir)

	supported, _ := DriverRuntimeSupportStatus("mariadb")
	if supported {
		t.Fatalf("mariadb 未安装时不应可用")
	}

	if !IsOptionalGoDriverBuildIncluded("mariadb") {
		supported, reason := DriverRuntimeSupportStatus("mariadb")
		if supported {
			t.Fatalf("精简构建下 mariadb 不应可用")
		}
		if reason == "" {
			t.Fatalf("精简构建下 mariadb 应返回不可用原因")
		}
		return
	}

	markerPath, err := ResolveOptionalGoDriverMarkerPath(tmpDir, "mariadb")
	if err != nil {
		t.Fatalf("解析 marker 路径失败: %v", err)
	}
	if err := os.MkdirAll(filepath.Dir(markerPath), 0o755); err != nil {
		t.Fatalf("创建 marker 目录失败: %v", err)
	}
	if err := os.WriteFile(markerPath, []byte("{}"), 0o644); err != nil {
		t.Fatalf("写入 marker 失败: %v", err)
	}
	executablePath, err := ResolveOptionalDriverAgentExecutablePath(tmpDir, "mariadb")
	if err != nil {
		t.Fatalf("解析 mariadb 代理路径失败: %v", err)
	}
	if runtime.GOOS == "windows" {
		selfPath, selfErr := os.Executable()
		if selfErr != nil {
			t.Fatalf("获取测试进程路径失败: %v", selfErr)
		}
		content, readErr := os.ReadFile(selfPath)
		if readErr != nil {
			t.Fatalf("读取测试进程失败: %v", readErr)
		}
		if err := os.WriteFile(executablePath, content, 0o755); err != nil {
			t.Fatalf("写入 mariadb 代理占位可执行文件失败: %v", err)
		}
	} else {
		if err := os.WriteFile(executablePath, []byte("placeholder"), 0o755); err != nil {
			t.Fatalf("写入 mariadb 代理占位文件失败: %v", err)
		}
	}

	supported, reason := DriverRuntimeSupportStatus("mariadb")
	if !supported {
		t.Fatalf("mariadb 安装后应可用，reason=%s", reason)
	}
}

func TestNewCompatibleDriversAreOptionalAgentDrivers(t *testing.T) {
	tmpDir := t.TempDir()
	SetExternalDriverDownloadDirectory(tmpDir)

	for _, driverType := range []string{"oceanbase", "opengauss", "open_gauss", "starrocks", "iris", "intersystems"} {
		if IsBuiltinDriver(driverType) {
			t.Fatalf("%s 不应是免安装内置驱动", driverType)
		}
		if !IsOptionalGoDriver(driverType) {
			t.Fatalf("%s 应走可选 driver-agent 链路", driverType)
		}
		supported, _ := DriverRuntimeSupportStatus(driverType)
		if supported {
			t.Fatalf("%s 未安装 agent 时不应可用", driverType)
		}
	}
}

func TestMySQLBuiltinRuntimeSupportAvailable(t *testing.T) {
	tmpDir := t.TempDir()
	SetExternalDriverDownloadDirectory(tmpDir)

	supported, reason := DriverRuntimeSupportStatus("mysql")
	if !supported {
		t.Fatalf("mysql 属于免安装内置驱动，应可用，reason=%s", reason)
	}
}
