/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bytesw.bytebot.service;

import com.bytesw.bytebot.http.FileValidationResponse;
import com.bytesw.bytebot.http.enums.ValidationStatusEnum;
import com.bytesw.bytebot.model.QuestionFile;
import com.bytesw.bytebot.repository.QuestionFileRepository;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import static org.assertj.core.api.Java6Assertions.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.ArgumentMatchers.any;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author Hernán Uriarte Melchor
 * @version 14/09/18.
 * <p>
 * <p>
 * Copyright (c) 2018 Byte, S.A. Todos los derechos reservados.
 * <p>
 * Este software constituye información confidencial y propietaria de Byte, S.A.
 * ("Información Confidencial"). Usted no debe develar dicha Información
 * Confidencial y debe usarla de acuerdo con los términos de aceptación de
 * licencia de uso que firmó con Byte.
 */
@RunWith(SpringRunner.class)
public class FileManagementServiceTest {

    @TestConfiguration
    static class UserServiceTestContextConfiguration {

        @MockBean
        private QuestionFileRepository questionFileRepository;

        @Bean
        public FileManagementService fileManagementService() {
            return new FileManagementService();
        }
    }

    @Autowired
    private FileManagementService fileManagementService;

    @Autowired
    private QuestionFileRepository questionFileRepository;

    @Before
    public void setUp() {

    }

    @Test
    public void validateAndSaveFile_whenFileHasInvalidExtension_SimpleError() throws IOException {
        InputStream inputData = new FileInputStream("src/test/resources/data/preguntas-ejemplo-sin-columna-doble-columna.xls");
        String uuid = "1f59cb41-778a-46f6-acfc-3625108275bb";
        MultipartFile xlsFileHeadersRepetead = new MockMultipartFile(
                "preguntas-ejemplo-sin-columna-doble-columna.xml",
                "preguntas-ejemplo-sin-columna-doble-columna.xml",
                MediaType.APPLICATION_XML_VALUE,
                inputData);

        FileValidationResponse response = fileManagementService.validateAndSaveFile(uuid, xlsFileHeadersRepetead);

        assertThat(response.getFileValidationResult().getStatus())
                .isEqualTo(ValidationStatusEnum.INCOMPATIBLE_EXTENSION);
    }

    @Test
    public void validateAndSaveFile_whenFileHasHeaderRepetead_ErrorWithDetails() throws IOException {
        InputStream inputData = new FileInputStream("src/test/resources/data/preguntas-ejemplo-sin-columna-doble-columna.xls");
        String uuid = "1f59cb41-778a-46f6-acfc-3625108275bb";
        MultipartFile xlsFileHeadersRepetead = new MockMultipartFile(
                "preguntas-ejemplo-sin-columna-doble-columna.xls",
                "preguntas-ejemplo-sin-columna-doble-columna.xls",
                "application/vnd.ms-excel",
                inputData);

        FileValidationResponse response = fileManagementService.validateAndSaveFile(uuid, xlsFileHeadersRepetead);

        assertThat(response.getFileValidationResult().getStatus())
                .isEqualTo(ValidationStatusEnum.HEADER_ERROR);
    }

    @Test
    public void validateAndSaveFile_whenFileHasBadContent_ErrorWithDetails() throws IOException {
        InputStream inputData = new FileInputStream("src/test/resources/data/preguntas-ejemplo-sin-contenido-espacios-blanco.xlsx");
        String uuid = "1f59cb41-778a-46f6-acfc-3625108275bb";
        MultipartFile xlsFileBadContent = new MockMultipartFile(
                "preguntas-ejemplo-sin-contenido-espacios-blanco.xlsx",
                "preguntas-ejemplo-sin-contenido-espacios-blanco.xlsx",
                "application/vnd.ms-excel",
                inputData);

        FileValidationResponse response = fileManagementService.validateAndSaveFile(uuid, xlsFileBadContent);

        assertThat(response.getFileValidationResult().getStatus())
                .isEqualTo(ValidationStatusEnum.CONTENT_ERROR);
    }

    @Test
    public void validateAndSaveFile_whenFileIsCorrect_thenIsSaved() throws IOException {
        InputStream inputData = new FileInputStream("src/test/resources/data/preguntas-ejemplo-base.xlsx");
        String uuid = "1f59cb41-778a-46f6-acfc-3625108275bb";
        MultipartFile xlsFile = new MockMultipartFile(
                "preguntas-ejemplo-base.xlsx",
                "preguntas-ejemplo-base.xlsx",
                "application/vnd.ms-excel",
                inputData);

        QuestionFile questionFileBD = new QuestionFile();

        questionFileBD.setUuid(uuid);
        questionFileBD.setName(xlsFile.getOriginalFilename());
        questionFileBD.setSize(xlsFile.getSize());
        questionFileBD.setUploadDate(LocalDateTime.now());
        questionFileBD.setData(xlsFile.getBytes());

        Mockito.when(questionFileRepository.save(any(QuestionFile.class)))
                .thenReturn(questionFileBD);
        
        FileValidationResponse response = fileManagementService.validateAndSaveFile(uuid, xlsFile);
        
        assertThat(response.getFileValidationResult().getStatus())
                .isEqualTo(ValidationStatusEnum.OK);
    }
}
