package virtualmachine

import "testing"

func TestCategorizeError(t *testing.T) {
	tests := []struct {
		name       string
		errorStr   string
		wantType   string
		wantReason string
	}{
		// API not supported errors
		{
			name:       "501 error",
			errorStr:   "501 Not Implemented",
			wantType:   "APINotSupported",
			wantReason: "ImportDiskAPINotImplemented",
		},
		{
			name:       "not implemented",
			errorStr:   "importdisk API is not implemented",
			wantType:   "APINotSupported",
			wantReason: "ImportDiskAPINotImplemented",
		},
		{
			name:       "importdisk error",
			errorStr:   "failed to use importdisk",
			wantType:   "APINotSupported",
			wantReason: "ImportDiskAPINotImplemented",
		},

		// Configuration errors
		{
			name:       "cannot get provider config",
			errorStr:   "cannot get provider config",
			wantType:   "ConfigurationError",
			wantReason: "InvalidConfiguration",
		},
		{
			name:       "cannot get credentials",
			errorStr:   "cannot get credentials",
			wantType:   "ConfigurationError",
			wantReason: "InvalidConfiguration",
		},
		{
			name:       "cannot find site",
			errorStr:   "cannot find site",
			wantType:   "ConfigurationError",
			wantReason: "InvalidConfiguration",
		},
		{
			name:       "cannot create proxmox client",
			errorStr:   "cannot create Proxmox client",
			wantType:   "ConfigurationError",
			wantReason: "InvalidConfiguration",
		},

		// Quota errors
		{
			name:       "quota exceeded",
			errorStr:   "quota exceeded",
			wantType:   "QuotaExceeded",
			wantReason: "ResourceQuotaExceeded",
		},
		{
			name:       "resource exceeded",
			errorStr:   "resource exceeded",
			wantType:   "QuotaExceeded",
			wantReason: "ResourceQuotaExceeded",
		},

		// Node health errors
		{
			name:       "node unhealthy",
			errorStr:   "node is unhealthy",
			wantType:   "NodeUnhealthy",
			wantReason: "NodeHealthCheckFailed",
		},
		{
			name:       "node not reachable",
			errorStr:   "node is not reachable",
			wantType:   "NodeUnhealthy",
			wantReason: "NodeHealthCheckFailed",
		},
		{
			name:       "node offline",
			errorStr:   "node is offline",
			wantType:   "NodeUnhealthy",
			wantReason: "NodeHealthCheckFailed",
		},

		// Image errors
		{
			name:       "image not found",
			errorStr:   "image not found in storage",
			wantType:   "ImageNotFound",
			wantReason: "ImageNotFoundInStorage",
		},
		{
			name:       "cannot find image",
			errorStr:   "cannot find image",
			wantType:   "ImageNotFound",
			wantReason: "ImageNotFoundInStorage",
		},

		// Lock errors
		{
			name:       "lock file error",
			errorStr:   "lock file timeout",
			wantType:   "LockError",
			wantReason: "LockFileTimeout",
		},
		{
			name:       "timeout error",
			errorStr:   "operation timeout",
			wantType:   "LockError",
			wantReason: "LockFileTimeout",
		},

		// Authentication errors
		{
			name:       "authentication error",
			errorStr:   "authentication failed",
			wantType:   "AuthenticationError",
			wantReason: "AuthenticationFailed",
		},
		{
			name:       "unauthorized",
			errorStr:   "unauthorized access",
			wantType:   "AuthenticationError",
			wantReason: "AuthenticationFailed",
		},
		{
			name:       "401 error",
			errorStr:   "401 Unauthorized",
			wantType:   "AuthenticationError",
			wantReason: "AuthenticationFailed",
		},
		{
			name:       "invalid credentials",
			errorStr:   "invalid credentials",
			wantType:   "AuthenticationError",
			wantReason: "AuthenticationFailed",
		},
		{
			name:       "forbidden",
			errorStr:   "forbidden",
			wantType:   "AuthenticationError",
			wantReason: "AuthenticationFailed",
		},
		{
			name:       "403 error",
			errorStr:   "403 Forbidden",
			wantType:   "AuthenticationError",
			wantReason: "AuthenticationFailed",
		},

		// Network errors
		{
			name:       "network error",
			errorStr:   "network connection failed",
			wantType:   "NetworkError",
			wantReason: "TransientNetworkFailure",
		},
		{
			name:       "connection error",
			errorStr:   "connection refused",
			wantType:   "NetworkError",
			wantReason: "TransientNetworkFailure",
		},
		{
			name:       "connection reset",
			errorStr:   "connection reset",
			wantType:   "NetworkError",
			wantReason: "TransientNetworkFailure",
		},
		{
			name:       "502 error",
			errorStr:   "502 Bad Gateway",
			wantType:   "NetworkError",
			wantReason: "TransientNetworkFailure",
		},
		{
			name:       "503 error",
			errorStr:   "503 Service Unavailable",
			wantType:   "NetworkError",
			wantReason: "TransientNetworkFailure",
		},

		// Creation failures
		{
			name:       "cannot create vm",
			errorStr:   "cannot create VM",
			wantType:   "CreationFailed",
			wantReason: "VMCreationFailed",
		},
		{
			name:       "failed to create",
			errorStr:   "failed to create VM",
			wantType:   "CreationFailed",
			wantReason: "VMCreationFailed",
		},

		// Unknown errors
		{
			name:       "unknown error",
			errorStr:   "something went wrong",
			wantType:   "Failed",
			wantReason: "UnknownError",
		},
		{
			name:       "empty error",
			errorStr:   "",
			wantType:   "Failed",
			wantReason: "UnknownError",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := categorizeError(tt.errorStr)
			if result.Type != tt.wantType {
				t.Errorf("categorizeError(%q).Type = %q, want %q", tt.errorStr, result.Type, tt.wantType)
			}
			if result.Reason != tt.wantReason {
				t.Errorf("categorizeError(%q).Reason = %q, want %q", tt.errorStr, result.Reason, tt.wantReason)
			}
		})
	}
}

func TestCategorizeError_CaseInsensitive(t *testing.T) {
	tests := []struct {
		name     string
		errorStr string
		wantType string
	}{
		{"uppercase", "AUTHENTICATION FAILED", "AuthenticationError"},
		{"mixed case", "AuThEnTiCaTiOn FaIlEd", "AuthenticationError"},
		{"lowercase", "authentication failed", "AuthenticationError"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := categorizeError(tt.errorStr)
			if result.Type != tt.wantType {
				t.Errorf("categorizeError(%q).Type = %q, want %q", tt.errorStr, result.Type, tt.wantType)
			}
		})
	}
}

