package cn.novalon.manage.sys.handler;

import cn.novalon.manage.sys.core.domain.SysExceptionLog;
import cn.novalon.manage.sys.core.service.ISysExceptionLogService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

import java.time.LocalDateTime;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class ExceptionLogServiceImplTest {

    @Mock
    private ISysExceptionLogService exceptionLogService;

    private ExceptionLogServiceImpl exceptionLogServiceImpl;

    @BeforeEach
    void setUp() {
        exceptionLogServiceImpl = new ExceptionLogServiceImpl(exceptionLogService);
    }

    @Test
    void testLogException() {
        SysExceptionLog savedLog = new SysExceptionLog();
        savedLog.setId(1L);
        savedLog.setTitle("测试异常");
        savedLog.setExceptionName("TestException");
        savedLog.setExceptionMsg("测试异常消息");
        savedLog.setMethodName("testMethod");
        savedLog.setIp("127.0.0.1");
        savedLog.setExceptionStack("测试堆栈信息");
        savedLog.setCreateTime(LocalDateTime.now());

        when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));

        StepVerifier.create(exceptionLogServiceImpl.logException(
                "测试异常",
                "TestException",
                "测试异常消息",
                "testMethod",
                "127.0.0.1",
                "测试堆栈信息"
        ))
                .verifyComplete();

        verify(exceptionLogService).save(any(SysExceptionLog.class));
    }

    @Test
    void testLogException_WithEmptyFields() {
        SysExceptionLog savedLog = new SysExceptionLog();
        savedLog.setId(1L);

        when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));

        StepVerifier.create(exceptionLogServiceImpl.logException(
                "",
                "",
                "",
                "",
                "",
                ""
        ))
                .verifyComplete();

        verify(exceptionLogService).save(any(SysExceptionLog.class));
    }

    @Test
    void testLogException_WithNullFields() {
        SysExceptionLog savedLog = new SysExceptionLog();
        savedLog.setId(1L);

        when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));

        StepVerifier.create(exceptionLogServiceImpl.logException(
                null,
                null,
                null,
                null,
                null,
                null
        ))
                .verifyComplete();

        verify(exceptionLogService).save(any(SysExceptionLog.class));
    }

    @Test
    void testLogException_WithLongStackTrace() {
        String longStackTrace = "a".repeat(10000);

        SysExceptionLog savedLog = new SysExceptionLog();
        savedLog.setId(1L);

        when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));

        StepVerifier.create(exceptionLogServiceImpl.logException(
                "测试异常",
                "TestException",
                "测试异常消息",
                "testMethod",
                "127.0.0.1",
                longStackTrace
        ))
                .verifyComplete();

        verify(exceptionLogService).save(any(SysExceptionLog.class));
    }
}
