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

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

import com.avaya.collaboration.businessdata.api.NoAttributeFoundException;
import com.avaya.collaboration.businessdata.api.ServiceData;
import com.avaya.collaboration.businessdata.api.ServiceNotFoundException;
import com.avaya.collaboration.dal.factory.CollaborationDataFactory;
import com.avaya.collaboration.ssl.util.SSLUtilityException;
import com.avaya.zephyr.platform.dal.api.ServiceUtil;
import com.avaya.zephyr.services.sample_services.OutboundHttpsSample.EncoderFI;
import com.avaya.zephyr.services.sample_services.OutboundHttpsSample.HttpClientProvider;
import com.avaya.zephyr.services.sample_services.OutboundHttpsSample.HttpClientSingleton;
import com.avaya.zephyr.services.sample_services.OutboundHttpsSample.HttpRequestResource;
import com.avaya.zephyr.services.sample_services.OutboundHttpsSample.ReplaceFI;
import java.io.IOException;
import java.util.ArrayList;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

@Path(value = "/myResource")
public class HttpRequestResourceImpl
        implements HttpRequestResource
{
    private ServiceData svcData;
    private HttpClientProvider httpClientProvider;
    private static final ReplaceFI replaceFI = input -> input.replaceAll("\\s+$", "");
    private static final EncoderFI base64FI =
            (accountId, authToken) -> Base64.encodeBase64String((byte[]) (accountId + ":" + authToken)
                    .getBytes());

    public HttpRequestResourceImpl()
    {
        this(CollaborationDataFactory.getServiceData((String) ServiceUtil.getServiceDescriptor().getName(),
                (String) ServiceUtil.getServiceDescriptor().getVersion()), HttpClientSingleton.INSTANCE);
    }

    HttpRequestResourceImpl(final ServiceData svcData, final HttpClientProvider httpClientProvider)
    {
        this.svcData = svcData;
        this.httpClientProvider = httpClientProvider;
    }

    @GET
    @Path(value = "/accountDetails")
    @Override
    public final String accountDetails() throws IOException,
            NoAttributeFoundException, ServiceNotFoundException, SSLUtilityException
    {
        final String authToken = this.setUpAccountDetails();
        final HttpClient client = this.httpClientProvider.getHttpClientBasedOnSSLContext();
        final HttpGet getMethod = new HttpGet("https://api.zang.io/v2/Accounts/" + replaceFI
                .removeTrailingWhitespaces(
                        this.svcData.getServiceAttribute("com.avaya.sample.zang.accountid")) +
                ".json");
        getMethod.addHeader("Authorization", "Basic " + authToken);
        final HttpResponse response = client.execute((HttpUriRequest) getMethod);
        final HttpEntity entity = response.getEntity();
        return EntityUtils.toString((HttpEntity) entity);
    }

    @GET
    @Path(value = "/carrierLookUp")
    @Override
    public final String carrierLookUp() throws IOException,
            NoAttributeFoundException, ServiceNotFoundException, SSLUtilityException
    {
        final String phoneNumber = replaceFI
                .removeTrailingWhitespaces(this.svcData.getServiceAttribute("com.avaya.sample.phonenumber"));
        return this.processCarrierLookUp(phoneNumber);
    }

    @GET
    @Path(value = "/carrierLookUpUI")
    public final String carrierLookUpUI(@QueryParam(value = "phoneNumber") final String phoneNumber)
            throws IOException, NoAttributeFoundException, ServiceNotFoundException, SSLUtilityException
    {
        return this.processCarrierLookUp(phoneNumber);
    }

    public final String processCarrierLookUp(final String phoneNumber)
            throws IOException, NoAttributeFoundException, ServiceNotFoundException, SSLUtilityException
    {
        final String authToken = this.setUpAccountDetails();
        final HttpClient client = this.httpClientProvider.getHttpClientBasedOnSSLContext();
        final HttpPost getPost = new HttpPost("https://api.zang.io/v2/Accounts/" +
                replaceFI.removeTrailingWhitespaces(
                        this.svcData.getServiceAttribute("com.avaya.sample.zang.accountid")) +
                "/Lookups/Carrier.json");
        getPost.addHeader("Authorization", "Basic " + authToken);
        final ArrayList<BasicNameValuePair> urlParameters = new ArrayList<BasicNameValuePair>();
        urlParameters.add(new BasicNameValuePair("PhoneNumber", phoneNumber));
        getPost.setEntity((HttpEntity) new UrlEncodedFormEntity(urlParameters));
        final HttpResponse response = client.execute((HttpUriRequest) getPost);
        final HttpEntity entity = response.getEntity();
        return EntityUtils.toString((HttpEntity) entity);
    }

    private String setUpAccountDetails() throws NoAttributeFoundException, ServiceNotFoundException
    {
        final String accountId = replaceFI
                .removeTrailingWhitespaces(this.svcData.getServiceAttribute("com.avaya.sample.zang.accountid"));
        final String authToken = this.svcData.getServiceEncryptedAttribute("com.avaya.sample.zang.authtoken");
        return base64FI.baseEncode(accountId, authToken);
    }
}
