/****************************************************************************
* Copyright Avaya Inc., All Rights Reserved.
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF Avaya Inc.
* The copyright notice above does not evidence any actual or intended publication of such source code.
* Some third-party source code components may have been modified from their original versions by Avaya Inc.
* The modifications are Copyright Avaya Inc., All Rights Reserved.
* Avaya Confidential & Restricted. May not be distributed further without written permission of
* the Avaya owner.
****************************************************************************/
package com.avaya.zephyr.services.sample_services.Authorization.TaskDashboard.provider;

import java.io.IOException;
import java.io.InputStream;

import javax.net.ssl.SSLContext;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.avaya.collaboration.ssl.util.SSLProtocolType;
import com.avaya.collaboration.ssl.util.SSLUtilityException;
import com.avaya.collaboration.ssl.util.SSLUtilityFactory;
import com.avaya.collaboration.util.logger.Logger;
import com.google.common.base.Strings;

final class HttpUtilProviderImpl implements HttpUtilProvider
{
    private SSLContext sslContext;
    private EndpointProvider endpointProvider;
    private CloseableHttpClient httpClient;
    private final Logger logger;

    HttpUtilProviderImpl(final EndpointProvider endpointProvider)
    {
        this(endpointProvider, null, Logger.getLogger(HttpUtilProviderImpl.class));
    }

    HttpUtilProviderImpl(final EndpointProvider endpointProvider, final SSLContext sslContext,
            final Logger logger)
    {
        this.sslContext = sslContext;
        this.endpointProvider = endpointProvider;
        this.logger = logger;
    }

    @Override
    public void buildHttpClient() throws SSLUtilityException
    {
        try
        {
            if (sslContext == null)
            {
                sslContext = SSLUtilityFactory.createSSLContext(SSLProtocolType.TLS);
            }
            final SSLConnectionSocketFactory sslsf =
                    new SSLConnectionSocketFactory(sslContext,
                            SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        }
        catch (final SSLUtilityException e)
        {
            logger.error("Exception while getting SSL Context", e);
            throw e;
        }
    }

    @Override
    public CloseableHttpClient getHttpClient()
    {
        return httpClient;
    }

    @Override
    public void closeHttpClient()
    {
        try
        {
            if (httpClient != null)
            {
                httpClient.close();
            }
        }
        catch (final IOException e)
        {
            logger.error("Caught exception while closing http client.", e);
        }
    }

    @Override
    public HttpGet createHttpGet(final String authorizationBearer)
    {
        final String url = endpointProvider.getResourceEndpoint();
        if (Strings.isNullOrEmpty(url))
        {
            return null;
        }
        final HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader("Authorization", authorizationBearer);
        return httpGet;
    }

    @Override
    public String getHttpResponseAsString(final HttpResponse response)
    {
        HttpEntity httpEntity = null;
        InputStream in = null;
        try
        {
            httpEntity = response.getEntity();
            in = httpEntity.getContent();
            return IOUtils.toString(in, "UTF-8");
        }
        catch (final IllegalStateException | IOException e)
        {
            logger.error("Error getting the response", e);
        }
        finally
        {
            if (in != null)
            {
                IOUtils.closeQuietly(in);
            }
            try
            {
                EntityUtils.consume(httpEntity);
            }
            catch (final IOException e)
            {
                logger.error("Error closing http entity", e);
            }
        }
        return null;
    }
}
