/*****************************************************************************
© 2017 Avaya Inc. All rights reserved. 
****************************************************************************/

package com.avaya.zephyr.services.sample_services.OutboundHttpsSample;

import static org.mockito.Mockito.when;

import java.io.IOException;

import javax.net.ssl.SSLContext;

import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.avaya.collaboration.ssl.util.SSLUtilityException;
import com.avaya.collaboration.ssl.util.SSLUtilityFactory;
import com.avaya.collaboration.util.logger.Logger;
import com.avaya.zephyr.common.testutils.deencapsulation.FieldReflection;
import com.avaya.zephyr.platform.dal.api.ServiceUtil;

@RunWith(PowerMockRunner.class)
@PrepareForTest(
{ HttpClientSingleton.class, AttributeReaderImpl.class, Logger.class, ServiceUtil.class, SSLUtilityFactory.class })
final public class HttpClientSingletonTest
{
    @Mock
    private CloseableHttpClient httpClientMock;

    @Mock
    private HttpClient httpClientNewMock;

    private AttributeReaderImpl attributeReaderImplMock;

    @Mock
    private Builder requestConfigBuilderMock;

    @Mock
    private SSLContext sslContextMock;

    @Mock
    private HttpClientBuilder httpClientBuilderMock;

    private Logger loggerMock;

    @Before
    public void setup() throws Exception
    {
        attributeReaderImplMock = PowerMockito.mock(AttributeReaderImpl.class);
        PowerMockito.whenNew(AttributeReaderImpl.class).withAnyArguments().thenReturn(attributeReaderImplMock);

        loggerMock = PowerMockito.mock(Logger.class);
        PowerMockito.mockStatic(Logger.class);
        when(Logger.getLogger(HttpClientSingleton.class)).thenReturn(loggerMock);
    }

    @Test
    public void getHttpClientBasedOnSSLContext() throws SSLUtilityException
    {
        FieldReflection.setField(HttpClientSingleton.class, HttpClientSingleton.INSTANCE, "client", httpClientMock);
        FieldReflection.setField(HttpClientSingleton.class, HttpClientSingleton.INSTANCE, "sslContext", sslContextMock);
        PowerMockito.mockStatic(SSLUtilityFactory.class);
        when(SSLUtilityFactory.createSSLContext()).thenReturn(sslContextMock);
        final HttpClient httpClient = HttpClientSingleton.INSTANCE.getHttpClientBasedOnSSLContext();
        Assert.assertNotNull(httpClient);
    }

    @Test
    public void getMyFqdnOrIpAddress()
    {
        FieldReflection.setField(HttpClientSingleton.class, HttpClientSingleton.INSTANCE, "myFqdnOrIpAddress", "zang.io.com");
        final String fqdn = HttpClientSingleton.INSTANCE.getMyFqdnOrIpAddress();
        Assert.assertEquals(fqdn, "zang.io.com");
    }

    @Test
    public void getAttributeReader() throws Exception
    {
        final AttributeReader attributeReader = HttpClientSingleton.INSTANCE.getAttributeReader();

        Assert.assertNotNull(attributeReader);
    }

    @Test
    public void requestConfigBuilder()
    {
        final Builder requestConfigBuilder = HttpClientSingleton.INSTANCE.getRequestConfigBuilder();

        Assert.assertNotNull(requestConfigBuilder);
    }

    @Test
    public void getSSLContext() throws SSLUtilityException
    {
        FieldReflection.setField(HttpClientSingleton.class, HttpClientSingleton.INSTANCE, "sslContext", sslContextMock);

        final SSLContext sslContext = HttpClientSingleton.INSTANCE.getSSLContext();

        Assert.assertNotNull(sslContext);
    }

    @Test
    public void getHttpClientBuilder()
    {
        final HttpClientBuilder httpClientBuilder = HttpClientSingleton.INSTANCE.getHttpClientBuilder();

        Assert.assertNotNull(httpClientBuilder);
    }

    @Test
    public void reset() throws IOException, SSLUtilityException
    {
        FieldReflection.setField(HttpClientSingleton.class, HttpClientSingleton.INSTANCE, "client", httpClientMock);
        FieldReflection.setField(HttpClientSingleton.class, HttpClientSingleton.INSTANCE, "myFqdnOrIpAddress", "zang.io.com");

        final HttpClient httpClient = HttpClientSingleton.INSTANCE.reset();

        Assert.assertNull(httpClient);
    }
}
