package com.ufund.api.ufundapi.controller;

import java.io.IOException;
import java.util.Map;
import static java.util.Map.entry;

import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;

import com.ufund.api.ufundapi.service.AuthService;

@RequestMapping("auth")
public class AuthControllerTest {

    private AuthController authController;
    private AuthService mockAuthService;
    private Map<String, String> authMap;

    @BeforeEach
    public void setupAuthController() {
        mockAuthService = mock(AuthService.class);
        authController = new AuthController(mockAuthService);

        authMap = Map.ofEntries(
                entry("Bob", "123")
        );
    }

    @Test
    public void testLogin() throws IllegalAccessException, IOException {
        // Setup
        String key = "123";

        // Mock
        when(mockAuthService.login(any(), any())).thenReturn(key);

        // Invoke
        ResponseEntity<String> response = authController.login(authMap);

        // Analyze
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals(key, response.getBody());
    }

    @Test
    public void testLoginUnauthorized() throws IllegalAccessException, IOException {
        // Mock
        when(mockAuthService.login(any(), any())).thenThrow(IllegalAccessException.class);

        // Invoke
        ResponseEntity<String> response = authController.login(authMap);

        // Analyze
        assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
    }

    @Test
    public void testLoginIOException() throws IllegalAccessException, IOException {
        // Mock
        when(mockAuthService.login(any(), any())).thenThrow(IOException.class);

        // Invoke
        ResponseEntity<String> response = authController.login(authMap);

        // Analyze
        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
    }

    @Test
    public void testLogout() {
        // Setup
        String key = "123";

        // Invoke
        ResponseEntity<Object> response = authController.logout(key);

        // Analyze
        assertEquals(HttpStatus.OK, response.getStatusCode());
    }

    @Test
    public void testLogoutIOException() throws IOException {
        // Setup
        String key = "123";

        // Mock
        doThrow(new IOException()).when(mockAuthService).logout(key);

        // Invoke
        ResponseEntity<Object> response = authController.logout(key);

        // Analyze
        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
    }
}