package com.eactive.eai.manage.inflow;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.test.util.ReflectionTestUtils;

/**
 * InflowTargetBucketController 단위 테스트.
 *
 * <p>Spring MVC를 기동하지 않고 컨트롤러를 직접 인스턴스화하여
 * 응답 구조(success, data, count, message)를 검증한다.
 * 클라이언트 관련 테스트는 ClientInflowTargetBucketControllerTest 에서 검증한다.
 */
class InflowTargetBucketControllerTest {

    private InflowTargetBucketController controller;
    private InflowTargetBucketService mockService;

    @BeforeEach
    void setUp() {
        controller  = new InflowTargetBucketController();
        mockService = mock(InflowTargetBucketService.class);
        ReflectionTestUtils.setField(controller, "bucketService", mockService);
    }

    // -------------------------------------------------------------------------
    // Helper
    // -------------------------------------------------------------------------

    private TargetBucketStatusDTO makeDTO(String id, String type) {
        TargetBucketStatusDTO dto = new TargetBucketStatusDTO();
        dto.setTargetId(id);
        dto.setTargetType(type);
        dto.setActivate(true);
        dto.setBuckets(Collections.emptyList());
        return dto;
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> body(ResponseEntity<?> response) {
        return (Map<String, Object>) response.getBody();
    }

    // =========================================================================
    // 어댑터 — 단일 조회
    // =========================================================================

    @Test
    void getAdapterBucketStatus_found_successTrueAndDataPresent() {
        TargetBucketStatusDTO dto = makeDTO("ADAPTER_A", "ADAPTER");
        when(mockService.getAdapterBucketStatus("ADAPTER_A")).thenReturn(dto);

        ResponseEntity<?> response = controller.getAdapterBucketStatus("ADAPTER_A");
        Map<String, Object> body = body(response);

        assertEquals(200, response.getStatusCodeValue());
        assertEquals(Boolean.TRUE, body.get("success"));
        assertSame(dto, body.get("data"));
        assertFalse(body.containsKey("message"));
    }

    @Test
    void getAdapterBucketStatus_notFound_successFalseWithAdapterId() {
        when(mockService.getAdapterBucketStatus("GHOST")).thenReturn(null);

        ResponseEntity<?> response = controller.getAdapterBucketStatus("GHOST");
        Map<String, Object> body = body(response);

        assertEquals(Boolean.FALSE, body.get("success"));
        assertTrue(body.get("message").toString().contains("GHOST"));
    }

    // =========================================================================
    // 어댑터 — 전체 조회
    // =========================================================================

    @Test
    void getAllAdapterBucketStatus_returnsListAndCount() {
        List<TargetBucketStatusDTO> list = Arrays.asList(
                makeDTO("A1", "ADAPTER"),
                makeDTO("A2", "ADAPTER")
        );
        when(mockService.getAllAdapterBucketStatus()).thenReturn(list);

        ResponseEntity<?> response = controller.getAllAdapterBucketStatus();
        Map<String, Object> body = body(response);

        assertEquals(Boolean.TRUE, body.get("success"));
        assertSame(list, body.get("data"));
        assertEquals(2, body.get("count"));
    }

    @Test
    void getAllAdapterBucketStatus_emptyList_countZero() {
        when(mockService.getAllAdapterBucketStatus()).thenReturn(Collections.emptyList());

        Map<String, Object> body = body(controller.getAllAdapterBucketStatus());

        assertEquals(Boolean.TRUE, body.get("success"));
        assertEquals(0, body.get("count"));
    }

    // =========================================================================
    // 인터페이스 — 단일 조회
    // =========================================================================

    @Test
    void getInterfaceBucketStatus_found_successTrue() {
        TargetBucketStatusDTO dto = makeDTO("IF_001", "INTERFACE");
        when(mockService.getInterfaceBucketStatus("IF_001")).thenReturn(dto);

        ResponseEntity<?> response = controller.getInterfaceBucketStatus("IF_001");
        Map<String, Object> body = body(response);

        assertEquals(Boolean.TRUE, body.get("success"));
        assertSame(dto, body.get("data"));
    }

    @Test
    void getInterfaceBucketStatus_notFound_successFalseWithInterfaceId() {
        when(mockService.getInterfaceBucketStatus("GHOST")).thenReturn(null);

        Map<String, Object> body = body(controller.getInterfaceBucketStatus("GHOST"));

        assertEquals(Boolean.FALSE, body.get("success"));
        assertTrue(body.get("message").toString().contains("GHOST"));
    }

    // =========================================================================
    // 인터페이스 — 전체 조회
    // =========================================================================

    @Test
    void getAllInterfaceBucketStatus_returnsListAndCount() {
        List<TargetBucketStatusDTO> list = Collections.singletonList(makeDTO("IF_001", "INTERFACE"));
        when(mockService.getAllInterfaceBucketStatus()).thenReturn(list);

        Map<String, Object> body = body(controller.getAllInterfaceBucketStatus());

        assertEquals(Boolean.TRUE, body.get("success"));
        assertEquals(1, body.get("count"));
    }
}
