package tech.easyflow.agent.runtime.document;

import org.junit.Assert;
import org.junit.Test;
import org.mockito.InOrder;
import org.mockito.Mockito;
import tech.easyflow.agent.config.AgentDocumentProperties;
import tech.easyflow.common.mq.config.MQProperties;
import tech.easyflow.common.mq.core.MQMessage;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * {@link AgentDocumentReadTaskConsumer} 超时状态回归测试。
 */
public class AgentDocumentReadTaskConsumerTest {

    /**
     * 验证读取超时时先提交超时状态，再中断工作线程。
     *
     * @throws Exception 消费器执行异常
     */
    @Test
    public void shouldMarkTimeoutBeforeCancellingWorker() throws Exception {
        AgentDocumentReaderService readerService = Mockito.mock(AgentDocumentReaderService.class);
        ExecutorService executor = Mockito.mock(ExecutorService.class);
        Future<?> future = Mockito.mock(Future.class);
        Mockito.doReturn(future).when(executor).submit(Mockito.any(Runnable.class));
        Mockito.when(future.get(Mockito.anyLong(), Mockito.eq(TimeUnit.MILLISECONDS)))
                .thenThrow(new TimeoutException("timeout"));
        AgentDocumentReadTaskConsumer consumer = new AgentDocumentReadTaskConsumer(
                readerService, new AgentDocumentProperties(), new MQProperties(), executor);
        MQMessage message = new MQMessage();
        message.setBody("{\"attachmentId\":\"attachment-1\"}");

        Assert.assertThrows(IllegalStateException.class, () -> consumer.handle(List.of(message)));

        InOrder order = Mockito.inOrder(future, readerService);
        order.verify(future).get(Mockito.anyLong(), Mockito.eq(TimeUnit.MILLISECONDS));
        order.verify(readerService).markTimeout("attachment-1");
        order.verify(future).cancel(true);
    }
}
