package com.workfusion.odf.api.domain;

import java.util.ArrayList;
import java.util.List;

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.mockito.Mockito;

import com.workfusion.odf.core.Intake;
import com.workfusion.odf.impl.processor.TransactionImporter;
import com.workfusion.odf.core.Module;
import com.workfusion.odf.service.TransactionService;
import com.workfusion.odf.service.serialization.BusinessProcessFormats;

public class IntakeImportExportTest {
    private TransactionImporter importer;

    private TransactionService transactionService;

    private Binding binding;

    private Intake intake;

    private Module testModule = new Module() {
        @Provides
        public TransactionImporter transactionImporter() {
            return importer;
        }

        @Provides
        public Binding binding() {
            return binding;
        }

        @Provides
        public TransactionService transactionService() {
            return transactionService;
        }
    };

    @BeforeEach
    public void init() {
        importer = Mockito.mock(TransactionImporter.class);
        transactionService = Mockito.mock(TransactionService.class);
        binding = Mockito.mock(Binding.class);

        intake = Intake.init(binding).override(testModule).get();
    }

    @Test
    public void transactionExport() {
        String transactionId = "123";
        Transaction exportTransaction = buildTransactionWithStaticLinks();
        Mockito.when(transactionService.byId(transactionId)).thenReturn(exportTransaction);
        String json = intake.exportTransactionAsJson(transactionId);
        Transaction transaction = BusinessProcessFormats.fromJson(json);
        Assertions.assertTrue(transaction.equals(exportTransaction));
    }

    @Test
    public void transactionImport() {
        String transactionId = "123";
        Transaction safeCopy = buildTransactionWithStaticLinks();
        Transaction exportTransaction = buildTransactionWithStaticLinks();
        exportTransaction.getDocs().get(0).setTextLink("localhost");
        String json = BusinessProcessFormats.toJson(safeCopy);

        Mockito.when(importer.transform(Mockito.any())).thenReturn(exportTransaction);
        Transaction importedTransaction = intake.importTransactionFromJson(transactionId, json);
        Mockito.verify(transactionService, Mockito.times(1)).update(exportTransaction);
        Assertions.assertEquals(exportTransaction, importedTransaction);
    }

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

        Document doc = new Document();
        doc.setId("1");
        doc.setName("name1");
        doc.setType("type1");
        doc.setTextLink("http://111.12.12.12/link1.html");
        doc.setTaggedTextLink("http://111.12.12.12/link1_tagged.html");
        doc.setOriginalDocumentLink("http://111.12.12.12/link1.xlsx");
        docs.add(doc);

        Document doc1 = new Document();
        doc1.setId("2");
        doc1.setName("name2");
        doc1.setType("type1");
        doc1.setTextLink("http://111.12.12.12/link2.html");
        doc1.setTaggedTextLink("http://111.12.12.12/link2_tagged.html");
        doc1.setOriginalDocumentLink("http://111.12.12.12/link2.xlsx");
        docs.add(doc1);

        transaction.setDocs(docs);

        return transaction;
    }
}
