/*
 * Copyright (c) eHealth
 */
package be.ehealth.business.mycarenetcommons.builders.impl;

import java.io.InputStream;
import java.util.UUID;

import org.junit.After;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.unitils.reflectionassert.ReflectionAssert;

import be.ehealth.business.mycarenetcommons.builders.BlobBuilder;
import be.ehealth.business.mycarenetcommons.builders.BlobBuilderFactory;
import be.ehealth.business.mycarenetcommons.domain.Blob;
import be.ehealth.technicalconnector.config.ConfigFactory;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.utils.ConnectorIOUtils;
import be.fgov.ehealth.technicalconnector.tests.session.SessionInitializer;


/**
 * Test for {@link BlobBuilder}
 * 
 * @author EHP
 * 
 */
public class BlobBuilderTest {

    private static BlobBuilder blobBuilder;

    private static byte[] content;

    private static String encodingType;

    private static String id;

    private static String contentType;

    @BeforeClass
    public static void init() throws Exception {
        blobBuilder = BlobBuilderFactory.getBlobBuilder("mycarenetcommons");

        // Params
        InputStream xmlFile = ConnectorIOUtils.getResourceAsStream("/examples/PostConsultationListeXml.xml");
        content = ConnectorIOUtils.getBytes(xmlFile);
        encodingType = "deflate";
        id = "_" + UUID.randomUUID().toString();
        contentType = "text/xml";
    }

    @After
    public void teardown() throws Exception {
        SessionInitializer.init("/be.ehealth.businessconnector.mycarenetcommons.test.properties", false);
    }

    @Test
    public void testBuildBlob() throws Exception {
        Blob expected = new Blob();
        expected.setContent(ConnectorIOUtils.compress(content, ConnectorIOUtils.COMPRESSION_ALGO_DEFLATE));
        expected.setContentEncoding(encodingType);
        expected.setContentType(contentType);
        expected.setId(id);
        expected.setHashValue(null);

        Blob actual = blobBuilder.build(content, encodingType, id, contentType);

        ReflectionAssert.assertReflectionEquals(expected, actual);
    }

    @Test
    public void testBuildBlobMessageNameOk() throws Exception {
        String messageName = "MessageName";
        Blob expected = new Blob();

        expected.setContent(ConnectorIOUtils.compress(content, ConnectorIOUtils.COMPRESSION_ALGO_DEFLATE));
        expected.setContentEncoding(encodingType);
        expected.setContentType(contentType);
        expected.setId(id);
        expected.setHashValue(null);
        expected.setMessageName(messageName);

        Blob actual = blobBuilder.build(content, encodingType, id, contentType, messageName);

        ReflectionAssert.assertReflectionEquals(expected, actual);
    }

    @Test(expected = junit.framework.AssertionFailedError.class)
    public void testBuildBlobMessageNameNok() throws Exception {
        String messageName = "MessageName";
        Blob expected = new Blob();

        expected.setContent(ConnectorIOUtils.compress(content, ConnectorIOUtils.COMPRESSION_ALGO_DEFLATE));
        expected.setContentEncoding(encodingType);
        expected.setContentType(contentType);
        expected.setId(id);
        expected.setHashValue(null);
        expected.setMessageName(messageName + "2");

        Blob actual = blobBuilder.build(content, encodingType, id, contentType, messageName);

        ReflectionAssert.assertReflectionEquals(expected, actual);
    }

    @Test
    public void testCheckAndRetrieveContentSuccess() throws Exception {
        Blob blob = blobBuilder.build(content, encodingType, id, contentType);
        blob.setHashTagRequired(false);
        blobBuilder.checkAndRetrieveContent(blob);
    }

    @Test(expected = TechnicalConnectorException.class)
    public void testCheckAndRetrieveContentFailsBadContent() throws Exception {
        Blob blob = blobBuilder.build(content, encodingType, id, contentType);
        blob.setContent("Hello".getBytes());

        blobBuilder.checkAndRetrieveContent(blob);
    }

    @Test(expected = TechnicalConnectorException.class)
    public void testCheckAndRetrieveContentFailsContentNull() throws Exception {
        Blob blob = blobBuilder.build(content, encodingType, id, contentType);
        blob.setContent(null);

        blobBuilder.checkAndRetrieveContent(blob);
    }

    @Test(expected = TechnicalConnectorException.class)
    public void testCheckAndRetrieveContentFailsBadHashValue() throws Exception {
        Blob blob = blobBuilder.build(content, encodingType, id, contentType);
        blob.setHashValue(null);

        blobBuilder.checkAndRetrieveContent(blob);
    }

    @Test(expected = TechnicalConnectorException.class)
    public void testCheckAndRetrieveContentFailsBlobNull() throws Exception {
        blobBuilder.checkAndRetrieveContent(null);
    }

    @Test
    public void testBuildWithOneParameterDefaultValueTrue() {
        try {
            ConfigFactory.setConfigLocation("/TestBlobBuilder.properties");
            BlobBuilder bBuilder = BlobBuilderFactory.getBlobBuilder("defaulttrue");
            Blob blob = bBuilder.build(content);
            Assert.assertEquals("666", blob.getId());
            Assert.assertEquals("none", blob.getContentEncoding());
            Assert.assertEquals("text/doc", blob.getContentType());
        } catch (TechnicalConnectorException e) {
            Assert.fail("unexpected error");
        }

    }

    @Test
    public void testBuildWithOneParameterDefaultValueFalse() {
        try {
            ConfigFactory.setConfigLocation("/TestBlobBuilder.properties");
            BlobBuilder bBuilder = BlobBuilderFactory.getBlobBuilder("defaultfalse");
            Blob blob = bBuilder.build(content);
            Assert.assertEquals("123456", blob.getId());
            Assert.assertEquals("deflate", blob.getContentEncoding());
            Assert.assertEquals("text/xml", blob.getContentType());
        } catch (TechnicalConnectorException e) {
            Assert.fail("unexpected error");
        }

    }

    @Test
    public void testBuildWithOneParameterNoDefaultValue() {
        try {
            ConfigFactory.setConfigLocation("/TestBlobBuilder.properties");
            BlobBuilder bBuilder = BlobBuilderFactory.getBlobBuilder(null);
            Blob blob = bBuilder.build(content);
            Assert.assertEquals("666", blob.getId());
            Assert.assertEquals("none", blob.getContentEncoding());
            Assert.assertEquals("text/doc", blob.getContentType());
        } catch (TechnicalConnectorException e) {
            Assert.fail("unexpected error");
        }

    }


    @Test
    public void testBuildWithDefaultValue() {
        try {
            BlobBuilder bBuilder = BlobBuilderFactory.getBlobBuilder("noExistingProject");
            Blob blob = bBuilder.build(content);
            Assert.assertEquals("blob", blob.getId());
            Assert.assertEquals("none", blob.getContentEncoding());
            Assert.assertEquals("text/xml", blob.getContentType());
        } catch (TechnicalConnectorException e) {
            Assert.fail("unexpected error");
        }

    }

}
