package agentidp

import (
	"strings"
	"testing"
)

func TestAgentIdPError_Error(t *testing.T) {
	err := &AgentIdPError{Code: "AgentNotFoundError", Message: "Agent not found.", HTTPStatus: 404}
	if err.Error() != "Agent not found." {
		t.Errorf("expected 'Agent not found.', got %q", err.Error())
	}
}

func TestParseAPIError_ValidBody(t *testing.T) {
	body := []byte(`{"code":"AgentNotFoundError","message":"Not found.","details":{"id":"x"}}`)
	err := parseAPIError(body, 404)
	if err.Code != "AgentNotFoundError" {
		t.Errorf("expected code AgentNotFoundError, got %q", err.Code)
	}
	if err.HTTPStatus != 404 {
		t.Errorf("expected status 404, got %d", err.HTTPStatus)
	}
	if err.Details == nil {
		t.Error("expected non-nil Details")
	}
}

func TestParseAPIError_UnparseableBody(t *testing.T) {
	err := parseAPIError([]byte("not json"), 500)
	if err.Code != "UNKNOWN_ERROR" {
		t.Errorf("expected UNKNOWN_ERROR, got %q", err.Code)
	}
	if err.HTTPStatus != 500 {
		t.Errorf("expected 500, got %d", err.HTTPStatus)
	}
}

func TestParseAPIError_EmptyCode(t *testing.T) {
	// Valid JSON but no "code" field → falls back to UNKNOWN_ERROR
	err := parseAPIError([]byte(`{"message":"oops"}`), 503)
	if err.Code != "UNKNOWN_ERROR" {
		t.Errorf("expected UNKNOWN_ERROR, got %q", err.Code)
	}
}

func TestParseOAuth2Error_ValidBody(t *testing.T) {
	body := []byte(`{"error":"invalid_client","error_description":"Bad credentials."}`)
	err := parseOAuth2Error(body, 401)
	if err.Code != "invalid_client" {
		t.Errorf("expected invalid_client, got %q", err.Code)
	}
	if err.Message != "Bad credentials." {
		t.Errorf("expected 'Bad credentials.', got %q", err.Message)
	}
	if err.HTTPStatus != 401 {
		t.Errorf("expected 401, got %d", err.HTTPStatus)
	}
}

func TestParseOAuth2Error_UnparseableBody(t *testing.T) {
	err := parseOAuth2Error([]byte("garbage"), 400)
	if err.Code != "UNKNOWN_ERROR" {
		t.Errorf("expected UNKNOWN_ERROR, got %q", err.Code)
	}
}

func TestNewNetworkError(t *testing.T) {
	cause := &testError{msg: "connection refused"}
	err := newNetworkError(cause)
	if err.Code != "NETWORK_ERROR" {
		t.Errorf("expected NETWORK_ERROR, got %q", err.Code)
	}
	if err.HTTPStatus != 0 {
		t.Errorf("expected HTTPStatus 0, got %d", err.HTTPStatus)
	}
	if !strings.Contains(err.Message, "connection refused") {
		t.Errorf("expected message to contain 'connection refused', got %q", err.Message)
	}
}

// testError is a simple error implementation for testing.
type testError struct{ msg string }

func (e *testError) Error() string { return e.msg }
