package com.workfusion.odf.impl.processor;

import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;

import groovy.lang.Binding;
import org.codejargon.feather.Provides;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.slf4j.Logger;

import com.workfusion.odf.api.domain.Document;
import com.workfusion.odf.api.domain.Transaction;
import com.workfusion.odf.core.Intake;
import com.workfusion.odf.core.Module;
import com.workfusion.odf.impl.converter.excel2html.ToHtmlConverter;
import com.workfusion.rpa.core.storage.S3Manager;

@ExtendWith(MockitoExtension.class)

public class ExcelToHtmlProcessorTest {
    @Inject
    private ExcelToHtmlProcessor excelToHtmlProcessor;

    private S3Manager s3Manager;

    private ToHtmlConverter htmlConverter;

    private Logger logger;

    private Module testModule = new Module(){
        @Provides
        public S3Manager s3Manager() {
            return s3Manager;
        }

        @Provides
        public Logger logger() {
            return logger;
        }

        @Provides
        public ToHtmlConverter htmlConverter() {
            return htmlConverter;
        }
    };

    @BeforeEach
    public void init() {
        s3Manager = Mockito.mock(S3Manager.class);
        logger = Mockito.mock(Logger.class);
        htmlConverter = Mockito.mock(ToHtmlConverter.class);
        Binding binding = new Binding();
        long start = System.currentTimeMillis();

        Intake intake = Intake.init(binding).override(testModule).injectFields(this).get();
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    @Test
    public void convertDocumentTestSuccess() {
        //given
        final Transaction transaction = getTransaction();

        //when
        Mockito.when(htmlConverter.convertToHTML(Mockito.any())).thenReturn(new byte[1]);
        Mockito.when(s3Manager.uploadFileToS3(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn("http://192.168.0.1/doc-upload/file.html");
        final Transaction result = excelToHtmlProcessor.transform(transaction);

        //then
        Assertions.assertEquals(0, result.getDocs().stream().filter(e -> e.isExcelDocument()).count());
        Assertions.assertEquals(2, result.getDocs().stream().filter(e -> isHTMLFile(e.getTextLink())).count());
        Assertions.assertEquals(4, result.getDocs().size());
    }

    @Test
    public void convertDocumentTestSuccessBlankTransaction() {
        //given

        final Transaction transaction =  new Transaction();
        transaction.setDocs(new ArrayList<>());
        transaction.setId("1");

        Assertions.assertEquals(0, transaction.getDocs().stream().filter(e -> e.isExcelDocument()).count());
        Assertions.assertEquals(0, transaction.getDocs().stream().filter(e -> isHTMLFile(e.getOriginalDocumentLink())).count());
        Assertions.assertEquals(0, transaction.getDocs().size());

        //when
        final Transaction result = excelToHtmlProcessor.transform(transaction);

        //then
        Assertions.assertEquals(0, result.getDocs().stream().filter(e -> e.isExcelDocument()).count());
        Assertions.assertEquals(0, result.getDocs().stream().filter(e -> isHTMLFile(e.getOriginalDocumentLink())).count());
        Assertions.assertEquals(0, result.getDocs().size());
    }

    private Transaction getTransaction() {
        final Transaction transaction = new Transaction();
        transaction.setId("1");
        final List<Document> docs = new ArrayList<>();

        Document doc = new Document();
        doc.setId("1");
        doc.setOriginalDocumentLink("link1.xlsx");
        docs.add(doc);

        Document doc1 = new Document();
        doc1.setId("2");
        doc1.setOriginalDocumentLink("link1.xls");
        docs.add(doc1);

        Document doc2 = new Document();
        doc2.setId("3");
        doc2.setOriginalDocumentLink("link1.xlsjj");
        docs.add(doc2);

        Document doc3 = new Document();
        doc3.setId("4");
        doc3.setOriginalDocumentLink("");
        docs.add(doc3);
        transaction.setDocs(docs);

        return transaction;
    }

    private  boolean isHTMLFile(String str) {
        return str !=null && str.endsWith(".html");
    }
}