package com.workfusion.odf.impl.processor;

import java.util.Collections;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;

import groovy.lang.Binding;
import org.codejargon.feather.Provides;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

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 static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.when;

import static com.workfusion.odf.impl.processor.DocumentOcrLinkProcessor.OCR_JSON_CONTEXT_NAME;
import static com.workfusion.odf.impl.processor.DocumentOcrLinkProcessor.OCR_TYPE_CONTEXT_NAME;

@ExtendWith(MockitoExtension.class)
class DocumentOcrLinkProcessorTest {

    private static final String TOOD_DOC_LINK = "https://wfinst-307-db1.workfusion.com/doc-upload/a888e56e-5359-4e91-86d7-db0fe0e9c2e7/40e1b745-66c5-4867-98f3-f8353b8372c1/0000002-xmlForCorrectedImage-tood.xml";

    private static final String TOOD_DOC_OCR_RESULT = "{\n" +
            "   \"xmlForCorrectedImage\":{\n" +
            "      \"original_document_url\":\"https://s3.amazonaws.com/wf.sharebox/mturchyn/dfsg/0000002.7E.ONTPZZ-20181101155933.pdf\",\n" +
            "      \"ocr_export_format\":\"xmlForCorrectedImage\",\n" +
            "      \"ocr_tood_document_url\":\"" + TOOD_DOC_LINK + "\",\n" +
            "      \"ocr_raw_processed_document_url\":\"https://wfinst-307-db1.workfusion.com/doc-upload/a888e56e-5359-4e91-86d7-db0fe0e9c2e7/40e1b745-66c5-4867-98f3-f8353b8372c1/0000002-xmlForCorrectedImage-raw_processed.xml\",\n" +
            "      \"ocr_document_format\":\"xml\",\n" +
            "      \"ocr_document_url\":\"https://wfinst-307-db1.workfusion.com/doc-upload/a888e56e-5359-4e91-86d7-db0fe0e9c2e7/40e1b745-66c5-4867-98f3-f8353b8372c1/0000002-xmlForCorrectedImage.xml\"\n" +
            "   }\n" +
            "}";

    @Mock
    private Binding context;
    @Mock
    private Map<String, String> params;

    @Inject
    private DocumentOcrLinkProcessor ocrLinkProcessor;

    private final Module testModule = new Module() {
        @Provides
        public Binding binding() {
            return context;
        }

        @Provides
        @Named("botConfigParams")
        public Map<String, String> params() {
            return params;
        }
    };

    @BeforeEach
    void init() {
        Intake.init(context).params(params).override(testModule).injectFields(this).get();
        
        when(params.get("_sys_doc_id")).thenReturn("1");
        when(context.hasVariable(OCR_TYPE_CONTEXT_NAME)).thenReturn(true);
        when(context.hasVariable(OCR_JSON_CONTEXT_NAME)).thenReturn(true);
        when(context.getVariable(OCR_TYPE_CONTEXT_NAME)).thenReturn("tood");
        when(context.getVariable(OCR_JSON_CONTEXT_NAME)).thenReturn(TOOD_DOC_OCR_RESULT);
    }

    @Test
    void shouldTransformToodDocument() {
        // given
        Transaction transaction = createTestTransaction();

        // when
        Transaction transformed = ocrLinkProcessor.transform(transaction);

        // then
        assertEquals(1, transformed.getDocs().size());
        assertEquals(TOOD_DOC_LINK, transformed.getDocs().get(0).getTextLink());
    }

    @Test
    void shouldReturnDocumentWithOcredStatus() {
        // given
        Transaction transaction = createTestTransaction();
        assertFalse(transaction.getDocs().get(0).isOcredDocument());

        // when
        Transaction transformed = ocrLinkProcessor.transform(transaction);

        // then
        assertTrue(transformed.getDocs().get(0).isOcredDocument());
    }

    private Transaction createTestTransaction() {
        Document document = new Document();
        document.setId("1");
        Transaction transaction = new Transaction();
        transaction.setDocs(Collections.singletonList(document));
        return transaction;
    }

}
