package com.gzzm.lobster.guardrails;

import com.gzzm.lobster.llm.ToolCall;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;

import static org.junit.Assert.*;

/**
 * 验证：重复调用 3 次触发 loop_detected；否则不触发。
 */
public class AgentLoopDetectorTest {

    @Test
    public void threeIdenticalCallsTripLoop() {
        AgentLoopDetector d = new AgentLoopDetector();
        ToolCall tc = new ToolCall("id1", "read_file", "{\"a\":1}");
        d.observe(Arrays.asList(tc), true);
        d.observe(Arrays.asList(new ToolCall("id2", "read_file", "{\"a\":1}")), true);
        AgentLoopDetector.LoopCheckResult r = d.observe(
                Arrays.asList(new ToolCall("id3", "read_file", "{\"a\":1}")), true);
        assertTrue(r.isTripped());
        assertEquals("loop_detected", r.getReason());
    }

    @Test
    public void differentArgsDoNotTrip() {
        AgentLoopDetector d = new AgentLoopDetector();
        assertFalse(d.observe(Arrays.asList(new ToolCall("id1", "read_file", "{\"a\":1}")), true).isTripped());
        assertFalse(d.observe(Arrays.asList(new ToolCall("id2", "read_file", "{\"a\":2}")), true).isTripped());
        assertFalse(d.observe(Arrays.asList(new ToolCall("id3", "read_file", "{\"a\":3}")), true).isTripped());
    }

    @Test
    public void noProgressForManyTurnsTrips() {
        AgentLoopDetector d = new AgentLoopDetector();
        AgentLoopDetector.LoopCheckResult r = null;
        for (int i = 0; i < 8; i++) {
            r = d.observe(Collections.<ToolCall>emptyList(), false);
        }
        assertNotNull(r);
        assertTrue(r.isTripped());
        assertEquals("no_progress", r.getReason());
    }
}
