package com.wishurgift.service;

import com.wishurgift.helper.ElementMaker;
import com.wishurgift.helper.UserMaker;
import com.wishurgift.helper.WishlistMaker;
import com.wishurgift.persistence.entity.Element;
import com.wishurgift.persistence.entity.Image;
import com.wishurgift.persistence.entity.Wishlist;
import com.wishurgift.persistence.repository.ElementRepository;
import com.wishurgift.persistence.repository.ImageRepository;
import com.wishurgift.service.bean.ImageServiceBean;
import com.wishurgift.service.dto.ImageDTO;
import com.wishurgift.service.dto.UserDTO;
import com.wishurgift.service.dto.WishlistDTO;
import com.wishurgift.service.dto.request.ImageRequestDTO;
import com.wishurgift.service.dto.transformer.ImageTransformer;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import java.util.Optional;

import static org.junit.Assert.*;

public class ImageServiceTest {

    @Mock
    ElementRepository elementRepository;

    @Mock
    ImageRepository imageRepository;

    @Mock
    WishlistService wishlistService;

    @InjectMocks
    ImageServiceBean service;

    @Before
    public void before() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void addTest() {
        Element element = ElementMaker.makeElement();
        ImageRequestDTO request = ElementMaker.makeImageRequestDTO();

        ImageDTO actual = service.add(element, request);
        assertEquals(request.getExt(), actual.getExt());
        assertEquals(request.getData(), actual.getData());
    }

    @Test
    public void removeTest() {
        long id = 8;
        UserDTO userDTO = UserMaker.makeUserDTO();
        Wishlist wishlist = WishlistMaker.makeWishlist();
        Image image = wishlist.getElements().get(0).getImages().get(0);

        Mockito.when(imageRepository.findById(id)).thenReturn(Optional.of(image));

        assertTrue(service.remove(userDTO, id));
    }

    @Test
    public void imageNotFoundRemoveTest() {
        long id = 8;
        UserDTO userDTO = UserMaker.makeUserDTO();

        Mockito.when(imageRepository.findById(id)).thenReturn(Optional.empty());

        assertFalse(service.remove(userDTO, id));
    }

    @Test
    public void unauthorizedRemoveTest() {
        long id = 8;
        UserDTO userDTO = UserMaker.makeUserDTO();
        userDTO.setId(2);
        Wishlist wishlist = WishlistMaker.makeWishlist();
        Image image = wishlist.getElements().get(0).getImages().get(0);

        Mockito.when(imageRepository.findById(id)).thenReturn(Optional.of(image));

        assertFalse(service.remove(userDTO, id));
    }

    @Test
    public void notInListRemoveTest() {
        long id = 8;
        UserDTO userDTO = UserMaker.makeUserDTO();
        Wishlist wishlist = WishlistMaker.makeWishlist();
        Image image = wishlist.getElements().get(0).getImages().get(0);
        wishlist.getElements().get(0).getImages().remove(0);

        Mockito.when(imageRepository.findById(id)).thenReturn(Optional.of(image));

        assertFalse(service.remove(userDTO, id));
    }

    @Test
    public void getImageTest() {
        long id = 8;
        UserDTO userDTO = UserMaker.makeUserDTO();
        Wishlist wishlist = WishlistMaker.makeWishlist();
        Image image = wishlist.getElements().get(0).getImages().get(0);
        WishlistDTO wishlistDTO = WishlistMaker.makeWishlistDTO();

        Mockito.when(imageRepository.findById(id)).thenReturn(Optional.of(image));
        Mockito.when(wishlistService.getWishlist(wishlist.getId(), userDTO)).thenReturn(wishlistDTO);

        ImageDTO actual = service.getImage(userDTO, id);
        assertEquals(ImageTransformer.entityToDto(image), actual);
    }

    @Test
    public void imageNotFoundGetImageTest() {
        long id = 8;
        UserDTO userDTO = UserMaker.makeUserDTO();

        Mockito.when(imageRepository.findById(id)).thenReturn(Optional.empty());

        ImageDTO actual = service.getImage(userDTO, id);
        assertNull(actual);
    }

    @Test
    public void unauthorizedGetImageTest() {
        long id = 8;
        UserDTO userDTO = UserMaker.makeUserDTO();
        Wishlist wishlist = WishlistMaker.makeWishlist();
        Image image = wishlist.getElements().get(0).getImages().get(0);

        Mockito.when(imageRepository.findById(id)).thenReturn(Optional.of(image));
        Mockito.when(wishlistService.getWishlist(wishlist.getId(), userDTO)).thenReturn(null);

        ImageDTO actual = service.getImage(userDTO, id);
        assertNull(actual);
    }

    @Test
    public void getImageNoUserTest() {
        long id = 8;
        Wishlist wishlist = WishlistMaker.makeWishlist();
        wishlist.setPublic(true);
        Image image = wishlist.getElements().get(0).getImages().get(0);

        Mockito.when(imageRepository.findById(id)).thenReturn(Optional.of(image));

        ImageDTO actual = service.getImage(null, id);
        assertEquals(ImageTransformer.entityToDto(image), actual);
    }

    @Test
    public void privateGetImageNoUserTest() {
        long id = 8;
        Wishlist wishlist = WishlistMaker.makeWishlist();
        wishlist.setPublic(false);
        Image image = wishlist.getElements().get(0).getImages().get(0);

        Mockito.when(imageRepository.findById(id)).thenReturn(Optional.of(image));

        ImageDTO actual = service.getImage(null, id);
        assertNull(actual);
    }

}
