package cockroach

import (
	"testing"
)

func TestSanitizeIdentifier(t *testing.T) {
	tests := []struct {
		input    string
		expected string
	}{
		{"simple", "simple"},
		{"with-dash", "with_dash"},
		{"with_underscore", "with_underscore"},
		{"UPPERCASE", "uppercase"},
		{"MixedCase", "mixedcase"},
		{"with spaces", "with_spaces"},
		{"with.dots", "with_dots"},
		{"123numeric", "123numeric"},
		{"special!@#$%", "special_____"},
		{"", ""},
		{"project-abc-123", "project_abc_123"},
	}

	for _, tt := range tests {
		t.Run(tt.input, func(t *testing.T) {
			result := sanitizeIdentifier(tt.input)
			if result != tt.expected {
				t.Errorf("sanitizeIdentifier(%q) = %q, want %q", tt.input, result, tt.expected)
			}
		})
	}
}

func TestQuoteIdent(t *testing.T) {
	tests := []struct {
		input    string
		expected string
	}{
		{"simple", `"simple"`},
		{"with space", `"with space"`},
		{`with"quote`, `"with""quote"`},
		{"", `""`},
	}

	for _, tt := range tests {
		t.Run(tt.input, func(t *testing.T) {
			result := quoteIdent(tt.input)
			if result != tt.expected {
				t.Errorf("quoteIdent(%q) = %q, want %q", tt.input, result, tt.expected)
			}
		})
	}
}

func TestGenerateToken(t *testing.T) {
	// Test that tokens are generated with correct length
	lengths := []int{16, 32, 64}
	for _, length := range lengths {
		token, err := generateToken(length)
		if err != nil {
			t.Errorf("generateToken(%d) returned error: %v", length, err)
			continue
		}
		// Hex encoding doubles the length
		expectedLen := length * 2
		if len(token) != expectedLen {
			t.Errorf("generateToken(%d) returned token of length %d, want %d", length, len(token), expectedLen)
		}
	}

	// Test that tokens are unique
	token1, _ := generateToken(32)
	token2, _ := generateToken(32)
	if token1 == token2 {
		t.Error("generateToken returned duplicate tokens")
	}
}

func TestDatabaseNameFor(t *testing.T) {
	p := &Provisioner{}

	tests := []struct {
		projectID string
		expected  string
	}{
		{"myproject", "project_myproject"},
		{"my-project", "project_my_project"},
		{"MY_PROJECT", "project_my_project"},
		{"123", "project_123"},
	}

	for _, tt := range tests {
		t.Run(tt.projectID, func(t *testing.T) {
			result := p.databaseNameFor(tt.projectID)
			if result != tt.expected {
				t.Errorf("databaseNameFor(%q) = %q, want %q", tt.projectID, result, tt.expected)
			}
		})
	}
}

func TestUsernameFor(t *testing.T) {
	p := &Provisioner{}

	tests := []struct {
		projectID string
		expected  string
	}{
		{"myproject", "project_myproject"},
		{"my-project", "project_my_project"},
		{"MY_PROJECT", "project_my_project"},
	}

	for _, tt := range tests {
		t.Run(tt.projectID, func(t *testing.T) {
			result := p.usernameFor(tt.projectID)
			if result != tt.expected {
				t.Errorf("usernameFor(%q) = %q, want %q", tt.projectID, result, tt.expected)
			}
		})
	}
}
