/*-
 * ============LICENSE_START=======================================================
 * OSAM
 * ================================================================================
 * Copyright (C) 2018 AT&T
 * ================================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============LICENSE_END=========================================================
 */



package org.onap.osam.aai;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.mockito.Mockito;
import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
import org.onap.portalsdk.core.util.SystemProperties;
import org.onap.osam.aai.model.AaiGetTenatns.GetTenantsResponse;
import org.onap.osam.aai.model.AaiNodeQueryResponse;
import org.onap.osam.aai.model.ResourceType;
import org.onap.osam.aai.util.AAIRestInterface;
import org.onap.osam.aai.util.HttpsAuthClient;
import org.onap.osam.aai.util.ServletRequestHelper;
import org.onap.osam.aai.util.SystemPropertyHelper;
import org.onap.osam.controllers.LocalWebConfig;
import org.onap.osam.exceptions.GenericUncheckedException;
import org.onap.osam.model.Subscriber;
import org.onap.osam.model.SubscriberList;
import org.onap.osam.model.probes.ExternalComponentStatus;
import org.onap.osam.model.probes.HttpRequestMetadata;
import org.onap.osam.model.probes.StatusMetadata;
import org.onap.osam.testUtils.TestUtils;
import org.springframework.http.HttpMethod;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import sun.security.provider.certpath.SunCertPathBuilderException;
import sun.security.validator.ValidatorException;

import javax.crypto.BadPaddingException;
import javax.net.ssl.SSLHandshakeException;
import javax.servlet.ServletContext;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.Response;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.testng.Assert.*;

@ContextConfiguration(classes = {LocalWebConfig.class, SystemProperties.class})
@WebAppConfiguration
public class AaiClientTest {

    private AaiClient aaiClientMock;
    private ServletContext servletContext;

    @BeforeMethod
    public void initMocks(){
        aaiClientMock = mock(AaiClient.class);
        aaiClientMock.logger = mock(EELFLoggerDelegate.class);
        servletContext = mock(ServletContext.class);

        when(servletContext.getRealPath(any(String.class))).thenReturn("");

        when(aaiClientMock.doAaiGet(any(String.class),any(Boolean.class))).thenReturn(null);
    }

    @DataProvider
    public static Object[][] logicalLinkData() {
        return new Object[][] {
                {"", "network/logical-links/logical-link/"},
                {"link", "network/logical-links/logical-link/link"}
        };
    }

    @Test(dataProvider = "logicalLinkData")
    public void getLogicalLink_Link_Is_Empty(String link, String expectedUrl) {

        when(aaiClientMock.getLogicalLink(any(String.class))).thenCallRealMethod();
        aaiClientMock.getLogicalLink(link);
        Mockito.verify(aaiClientMock).doAaiGet(argThat(equalToIgnoringCase(expectedUrl)),any(Boolean.class));
    }

    @DataProvider
    public static Object[][] subscribersResults() {
        return new Object[][] {
                {new SubscriberList(new ArrayList<Subscriber>() {{ add(new Subscriber());  add(new Subscriber()); }}), true},
                {new SubscriberList(new ArrayList<Subscriber>() {{ add(new Subscriber()); }}), true},
                {new SubscriberList(new ArrayList<Subscriber>()), false}
        };
    }

    @Test(dataProvider = "subscribersResults")
    public void testProbeAaiGetAllSubscribers_returnsTwoToZeroSubscribers_ResultsAsExpected(SubscriberList subscribers, boolean isAvailable){
        ExternalComponentStatus expectedStatus = new ExternalComponentStatus(ExternalComponentStatus.Component.AAI,isAvailable, new HttpRequestMetadata(
                HttpMethod.GET,
                200,
                "url",
                "rawData",
                isAvailable ? "OK" : "No subscriber received",
                0
        ));
        Mockito.when(aaiClientMock.getAllSubscribers(true)).thenReturn(
                new AaiResponseWithRequestInfo<>(
                        HttpMethod.GET, "url", new AaiResponse<>(subscribers, null, 200),
                        "rawData"));
        Mockito.when(aaiClientMock.probeAaiGetAllSubscribers()).thenCallRealMethod();
        ExternalComponentStatus result  = aaiClientMock.probeAaiGetAllSubscribers();
        assertThat(statusDataReflected(result),is(statusDataReflected(expectedStatus)));
        assertThat(requestMetadataReflected(result.getMetadata()),is(requestMetadataReflected(expectedStatus.getMetadata())));
    }

    //serialize fields except of fields we cannot know ahead of time
    private static String requestMetadataReflected(StatusMetadata metadata) {
        return new ReflectionToStringBuilder(metadata, ToStringStyle.SHORT_PREFIX_STYLE)
                .setExcludeFieldNames("duration")
                .toString();
    }

    private static String statusDataReflected(ExternalComponentStatus status) {
        return new ReflectionToStringBuilder(status, ToStringStyle.SHORT_PREFIX_STYLE)
                .setExcludeFieldNames("metadata")
                .toString();
    }

    @DataProvider
    public static Object[][] rawData() {
        return new Object[][]{
                {"errorMessage", }, {""}, {null}
        };
    }

    @Test(dataProvider = "rawData")
    public void testProbeAaiGetFullSubscribersWithNullResponse_returnsNotAvailableWithErrorRawData(String rawData){
        Mockito.when(aaiClientMock.getAllSubscribers(true)).thenReturn(
                new AaiResponseWithRequestInfo<>(HttpMethod.GET, "url", null,
                        rawData));
        ExternalComponentStatus result = callProbeAaiGetAllSubscribersAndAssertNotAvailable();
        assertThat(result.getMetadata(), instanceOf(HttpRequestMetadata.class));
        assertEquals(((HttpRequestMetadata) result.getMetadata()).getRawData(), rawData);
    }

    @DataProvider
    public static Object[][] exceptions() {
        return new Object[][] {
                {"NullPointerException", "errorMessage",
                        new ExceptionWithRequestInfo(HttpMethod.GET, "url",
                                "errorMessage", null, new NullPointerException())},
                {"RuntimeException", null,
                        new ExceptionWithRequestInfo(HttpMethod.GET, "url",
                                null, null, new RuntimeException())},
                {"RuntimeException", null,
                        new RuntimeException()},
        };
    }

    @Test(dataProvider = "exceptions")
    public void testProbeAaiGetFullSubscribersWithNullResponse_returnsNotAvailableWithErrorRawData(String description, String expectedRawData, Exception exception){
        Mockito.when(aaiClientMock.getAllSubscribers(true)).thenThrow(exception);
        ExternalComponentStatus result = callProbeAaiGetAllSubscribersAndAssertNotAvailable();
        if (exception instanceof ExceptionWithRequestInfo) {
            assertThat(result.getMetadata(), instanceOf(HttpRequestMetadata.class));
            assertEquals(((HttpRequestMetadata) result.getMetadata()).getRawData(), expectedRawData);
        }
        assertThat(result.getMetadata().getDescription(), containsString(description));
    }

    private ExternalComponentStatus callProbeAaiGetAllSubscribersAndAssertNotAvailable() {
        Mockito.when(aaiClientMock.probeAaiGetAllSubscribers()).thenCallRealMethod();
        ExternalComponentStatus result  = aaiClientMock.probeAaiGetAllSubscribers();
        assertFalse(result.isAvailable());
        return result;
    }


    @Test
    public void getTenants_Arguments_Are_Null_Or_Empty() {

        when(aaiClientMock.getTenants(any(String.class), any(String.class))).thenCallRealMethod();

        AaiResponse response = aaiClientMock.getTenants("", "");

        assertEquals(response.getErrorMessage(), "{\"statusText\":\" Failed to retrieve LCP Region & Tenants from A&AI, Subscriber ID or Service Type is missing.\"}");


        response = aaiClientMock.getTenants(null, null);

        assertEquals(response.getErrorMessage(), "{\"statusText\":\" Failed to retrieve LCP Region & Tenants from A&AI, Subscriber ID or Service Type is missing.\"}");
    }

    @Test
    public void getTenants_Arguments_Are_Valid_But_Tenants_Not_Exist() {

        when(aaiClientMock.getTenants(any(String.class), any(String.class))).thenCallRealMethod();

        Response generalEmptyResponse = mock(Response.class);
        when(aaiClientMock.doAaiGet(any(String.class),any(Boolean.class))).thenReturn(generalEmptyResponse);

        AaiResponse response = aaiClientMock.getTenants("subscriberId", "serviceType");

        assertEquals(response.getErrorMessage(), "{\"statusText\":\" A&AI has no LCP Region & Tenants associated to subscriber 'subscriberId' and service type 'serviceType'\"}");

    }

    @Test
    public void getTenants_Arguments_Are_Valid_Get_The_Tenanats() {

        when(aaiClientMock.getTenants(any(String.class), any(String.class))).thenCallRealMethod();


        Response generalEmptyResponse = mock(Response.class);

        when(generalEmptyResponse.readEntity(String.class)).thenReturn(tenantResponseRaw);
        when(generalEmptyResponse.getStatus()).thenReturn(200);
        when(generalEmptyResponse.getStatusInfo()).thenReturn(new Response.StatusType() {
            @Override
            public int getStatusCode() {
                return 200;
            }

            @Override
            public Response.Status.Family getFamily() {
                return Response.Status.Family.SUCCESSFUL;
            }

            @Override
            public String getReasonPhrase() {
                return null;
            }
        });


        when(aaiClientMock.doAaiGet(any(String.class),any(Boolean.class))).thenReturn(generalEmptyResponse);

        AaiResponse<GetTenantsResponse[]> response = aaiClientMock.getTenants("subscriberId", "serviceType");

        Assert.assertTrue(response.t.length> 0);
    }

    final String tenantResponseRaw ="" +
            "{" +
            "\"service-type\": \"VIRTUAL USP\"," +
            "\"resource-version\": \"1494001841964\"," +
            "\"relationship-list\": {" +
            "\"relationship\": [{" +
            "\"related-to\": \"tenant\"," +
            "\"related-link\": \"/aai/v11/cloud-infrastructure/cloud-regions/cloud-region/att-aic/AAIAIC25/tenants/tenant/092eb9e8e4b7412e8787dd091bc58e86\"," +
            "\"relationship-data\": [{" +
            "\"relationship-key\": \"cloud-region.cloud-owner\"," +
            "\"relationship-value\": \"att-aic\"" +
            "}," +
            "{" +
            "\"relationship-key\": \"cloud-region.cloud-region-id\"," +
            "\"relationship-value\": \"AAIAIC25\"" +
            "}," +
            "{" +
            "\"relationship-key\": \"tenant.tenant-id\"," +
            "\"relationship-value\": \"092eb9e8e4b7412e8787dd091bc58e86\"" +
            "}" +
            "]," +
            "\"related-to-property\": [{" +
            "\"property-key\": \"tenant.tenant-name\"," +
            "\"property-value\": \"USP-SIP-IC-24335-T-01\"" +
            "}]" +
            "}]" +
            "}" +
            "}";

    @DataProvider
    public static Object[][] resourceTypesProvider() {
        return new Object[][] {
                {"service-instance", ResourceType.SERVICE_INSTANCE},
                {"generic-vnf", ResourceType.GENERIC_VNF},
                {"vf-module", ResourceType.VF_MODULE}
        };
    }

    @Test(dataProvider = "resourceTypesProvider")
    public void aaiNodeQueryResponseDeserializationTest(String resourceType, ResourceType expectedResourceType) throws IOException {
        String link = "/aai/v12/business/customers/customer/a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb/service-subscriptions/service-subscription/Nimbus/service-instances/service-instance/7131d483-b450-406f-8e30-0c650645fc67";
        String json =
                "{\"result-data\": [{" +
                    "\"resource-type\": \""+resourceType+"\"," +
                    "\"resource-link\": \""+ link+ "\"" +
                "}]}";

        AaiNodeQueryResponse nodeQueryResponse = new ObjectMapper().readValue(json, AaiNodeQueryResponse.class);
        assertThat(nodeQueryResponse.resultData.get(0).resourceLink, equalTo(link));
        assertThat(nodeQueryResponse.resultData.get(0).resourceType, is(expectedResourceType));
    }

    @Test
    public void aaiNodeQueryEmptyResponseDeserializationTest() throws IOException{
        String json = "{}";
        AaiNodeQueryResponse nodeQueryResponse = new ObjectMapper().readValue(json, AaiNodeQueryResponse.class);
        assertNull(nodeQueryResponse.resultData);
    }

    @DataProvider
    public static Object[][] nameAndResourceTypeProvider() {
        return new Object[][] {
                {"SRIOV_SVC", ResourceType.SERVICE_INSTANCE, "search/nodes-query?search-node-type=service-instance&filter=service-instance-name:EQUALS:SRIOV_SVC"},
                {"b1707vidnf", ResourceType.GENERIC_VNF, "search/nodes-query?search-node-type=generic-vnf&filter=vnf-name:EQUALS:b1707vidnf"},
                {"connectivity_test", ResourceType.VF_MODULE, "search/nodes-query?search-node-type=vf-module&filter=vf-module-name:EQUALS:connectivity_test"},
                {"MjVg1234", ResourceType.VOLUME_GROUP, "search/nodes-query?search-node-type=volume-group&filter=volume-group-name:EQUALS:MjVg1234"}
        };
    }

    @Test(dataProvider = "nameAndResourceTypeProvider")
    public void whenSearchNodeTypeByName_callRightAaiPath(String name, ResourceType type, String expectedUrl) {
        when(aaiClientMock.searchNodeTypeByName(any(String.class), any(ResourceType.class))).thenCallRealMethod();
        aaiClientMock.searchNodeTypeByName(name, type);
        Mockito.verify(aaiClientMock).doAaiGet(eq(expectedUrl), eq(false));
    }

    @DataProvider
    public static Object[][] aaiClientInternalExceptions() {
        return Stream.<Pair<Class<? extends Throwable>, UncheckedBiConsumer<HttpsAuthClient, Client>>>of(

                // Exception out of httpsAuthClientMock
                Pair.of(CertificateException.class, (httpsAuthClientMock, javaxClientMock) -> {
                    final CertificateException e0 = new CertificateException("No X509TrustManager implementation available");
                    SSLHandshakeException e = new SSLHandshakeException(e0.toString());
                    e.initCause(e0);

                    when(httpsAuthClientMock.getClient(any())).thenThrow(e);
                }),

                Pair.of(StringIndexOutOfBoundsException.class, mockExceptionOnClientProvider(new StringIndexOutOfBoundsException(4))),

                Pair.of(NullPointerException.class, mockExceptionOnClientProvider(new NullPointerException("null"))),

                Pair.of(FileNotFoundException.class, mockExceptionOnClientProvider(new FileNotFoundException("vid/WEB-INF/cert/aai-client-cert.p12"))),

                Pair.of(BadPaddingException.class, mockExceptionOnClientProvider(
                        new IOException("keystore password was incorrect", new BadPaddingException("Given final block not properly padded")))
                ),
                Pair.of(GenericUncheckedException.class, mockExceptionOnClientProvider(new GenericUncheckedException("basa"))),

                Pair.of(NullPointerException.class, (httpsAuthClientMock, javaxClientMock) ->
                        when(httpsAuthClientMock.getClient(any())).thenReturn(null)),


                // Exception out of javax's Client
                Pair.of(SSLHandshakeException.class, (httpsAuthClientMock, javaxClientMock) -> {
                    when(javaxClientMock.target(anyString())).thenThrow(
                            new ProcessingException(new SSLHandshakeException("Received fatal alert: certificate_expired"))
                    );
                }),

                Pair.of(SunCertPathBuilderException.class, (httpsAuthClientMock, javaxClientMock) -> {
                    SunCertPathBuilderException e0 = new SunCertPathBuilderException("unable to find valid certification path to requested target");
                    when(javaxClientMock.target(anyString())).thenThrow(
                            new ProcessingException(new ValidatorException("PKIX path building failed: " + e0.toString(), e0))
                    );
                }),

                Pair.of(GenericUncheckedException.class, (httpsAuthClientMock, javaxClientMock) ->
                        when(javaxClientMock.target(anyString())).thenThrow(new GenericUncheckedException("basa")))

        ).flatMap(l -> Stream.of(
                // double each case to propagateExceptions = true/false, to verify that "don't propagate" really still work
                ImmutableList.of(l.getLeft(), l.getRight(), true).toArray(),
                ImmutableList.of(l.getLeft(), l.getRight(), false).toArray()
        )).collect(Collectors.toList()).toArray(new Object[][]{});
    }

    private static UncheckedBiConsumer<HttpsAuthClient, Client> mockExceptionOnClientProvider(Exception e) {
        return (httpsAuthClientMock, javaxClientMock) ->
                when(httpsAuthClientMock.getClient(any())).thenThrow(e);
    }

    @Test(dataProvider = "aaiClientInternalExceptions")
    public void propagateExceptions_internalsThrowException_ExceptionRethrown(Class<? extends Throwable> expectedType, BiConsumer<HttpsAuthClient, Client> setupMocks, boolean propagateExceptions) throws Exception {

        // prepare mocks
        HttpsAuthClient httpsAuthClientMock = mock(HttpsAuthClient.class);
        TestUtils.JavaxRsClientMocks mocks = new TestUtils.JavaxRsClientMocks();
        Client javaxClientMock = mocks.getFakeClient();
        Response responseMock = mocks.getFakeResponse();

        // prepare real AAIRestInterface and AaiClient, and wire mocks
        AAIRestInterface aaiRestInterface = new AAIRestInterface(httpsAuthClientMock, new ServletRequestHelper(), new SystemPropertyHelper());
        final AaiClient aaiClient = new AaiClient(aaiRestInterface, null);
        when(httpsAuthClientMock.getClient(any())).thenReturn(javaxClientMock);

        // define atomic method under test, including reset of "aaiRestInterface.client"
        final Function<Boolean, Response> doAaiGet = (propagateExceptions1) -> {
            try {
                FieldUtils.writeField(aaiRestInterface, "client", null, true);
                return aaiClient.doAaiGet("uri", false, propagateExceptions1).getResponse();
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        };

        // verify setup again
        assertThat("mocks setup should make doAaiGet return our responseMock", doAaiGet.apply(true), is(sameInstance(responseMock)));


        /// TEST:
        setupMocks.accept(httpsAuthClientMock, javaxClientMock);

        try {
            final Response response = doAaiGet.apply(propagateExceptions);
        } catch (Exception e) {
            if (propagateExceptions) {
                assertThat("root cause incorrect for " + ExceptionUtils.getStackTrace(e), ExceptionUtils.getRootCause(e), instanceOf(expectedType));
                return; // ok, done
            } else {
                // Verify that "don't propagate" really still work
                Assert.fail("calling doAaiGet when propagateExceptions is false must result with no exception", e);
            }
        }

        // If no exception caught
        // We're asserting that the legacy behaviour is still in place. Hopefully
        // one day we will remove the non-propagateExceptions case
        assertFalse(propagateExceptions, "calling doAaiGet when propagateExceptions is 'true' must result with an exception (in this test)");
    }

    @FunctionalInterface
    public interface UncheckedBiConsumer<T, U> extends BiConsumer<T, U> {
        @Override
        default void accept(T t, U u) {
            try {
                acceptThrows(t, u);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        void acceptThrows(T t, U u) throws Exception;
    }
}
