package ai.sentryagent.idp;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class AgentIdPExceptionTest {

    @Test
    void constructor_setsFields() {
        AgentIdPException ex = new AgentIdPException("AgentNotFoundError", "Not found.", 404);
        assertEquals("AgentNotFoundError", ex.getCode());
        assertEquals("Not found.", ex.getMessage());
        assertEquals(404, ex.getHttpStatus());
        assertNull(ex.getDetails());
    }

    @Test
    void fromApiError_validBody() {
        String body = "{\"code\":\"AgentNotFoundError\",\"message\":\"Not found.\"}";
        AgentIdPException ex = AgentIdPException.fromApiError(body, 404);
        assertEquals("AgentNotFoundError", ex.getCode());
        assertEquals("Not found.", ex.getMessage());
        assertEquals(404, ex.getHttpStatus());
    }

    @Test
    void fromApiError_emptyCode_fallsBackToUnknown() {
        String body = "{\"message\":\"oops\"}";
        AgentIdPException ex = AgentIdPException.fromApiError(body, 503);
        assertEquals("UNKNOWN_ERROR", ex.getCode());
        assertEquals(503, ex.getHttpStatus());
    }

    @Test
    void fromApiError_unparseable_fallsBackToUnknown() {
        AgentIdPException ex = AgentIdPException.fromApiError("not json", 500);
        assertEquals("UNKNOWN_ERROR", ex.getCode());
        assertEquals(500, ex.getHttpStatus());
    }

    @Test
    void fromOAuth2Error_validBody() {
        String body = "{\"error\":\"invalid_client\",\"error_description\":\"Bad credentials.\"}";
        AgentIdPException ex = AgentIdPException.fromOAuth2Error(body, 401);
        assertEquals("invalid_client", ex.getCode());
        assertEquals("Bad credentials.", ex.getMessage());
        assertEquals(401, ex.getHttpStatus());
    }

    @Test
    void fromOAuth2Error_unparseable_fallsBackToUnknown() {
        AgentIdPException ex = AgentIdPException.fromOAuth2Error("garbage", 400);
        assertEquals("unknown_error", ex.getCode());
    }

    @Test
    void networkError_setsCodeAndCause() {
        RuntimeException cause = new RuntimeException("connection refused");
        AgentIdPException ex = AgentIdPException.networkError(cause);
        assertEquals("NETWORK_ERROR", ex.getCode());
        assertEquals(0, ex.getHttpStatus());
        assertSame(cause, ex.getCause());
        assertTrue(ex.getMessage().contains("connection refused"));
    }

    @Test
    void toString_containsCodeAndStatus() {
        AgentIdPException ex = new AgentIdPException("CODE", "msg", 400);
        assertTrue(ex.toString().contains("CODE"));
        assertTrue(ex.toString().contains("400"));
    }
}
