/*-
 * ============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.controllers;

import com.google.common.collect.ImmutableMap;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import org.onap.portalsdk.core.web.support.UserUtils;
import org.onap.osam.filters.PromiseEcompRequestIdFilter;
import org.springframework.mock.web.MockHttpServletResponse;
import org.testng.annotations.Test;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
import static org.onap.portalsdk.core.util.SystemProperties.ECOMP_REQUEST_ID;

@Test
public class PromiseEcompRequestIdFilterTest {

    private final String anotherHeader = "ANDREI_RUBLEV";
    private final String anotherValue = "foo value";
    private final String mixedCaseHeader = "x-ecomp-REQUESTID";

    @Test
    public void givenRequestIdHeader_headerValueNotChanged() throws IOException, ServletException {

        final String someTxId = "863850e2-8545-4efd-94b8-afba5f52b3d5";

        final ImmutableMap<String, String> incomingRequestHeaders = ImmutableMap.of(
                anotherHeader, anotherValue,
                ECOMP_REQUEST_ID, someTxId
        );

        buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(incomingRequestHeaders, specificTxId(someTxId));
    }

    @Test
    public void givenMixedCaseRequestIdHeader_headerValueNotChanged() throws IOException, ServletException {

        final String someTxId = "729bbd8d-b0c2-4809-a794-dcccd9cda2c0";

        final ImmutableMap<String, String> incomingRequestHeaders = ImmutableMap.of(
                mixedCaseHeader, someTxId,
                anotherHeader, anotherValue
        );

        buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(incomingRequestHeaders, specificTxId(someTxId));
    }

    @Test
    public void givenNoRequestIdHeader_headerValueWasGenerated() throws IOException, ServletException {

        final ImmutableMap<String, String> incomingRequestHeaders = ImmutableMap.of(
                anotherHeader, anotherValue
        );

        buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(incomingRequestHeaders, UserUtils::getRequestId);
    }

    
    private void buildRequestThenRunThroughFilterAndAssertResultRequestHeaders(
            ImmutableMap<String, String> originalRequestHeaders,
            Function<HttpServletRequest, String> txIdExtractor
    ) throws IOException, ServletException {
        HttpServletRequest servletRequest = createMockedHttpServletRequest(originalRequestHeaders);
        HttpServletResponse servletResponse = createMockedHttpServletResponse();

        final FilterChain capturingFilterChain = Mockito.mock(FilterChain.class);

        //////////////////
        //
        // doFilter() is the function under test
        //
        new PromiseEcompRequestIdFilter().doFilter(servletRequest, servletResponse, capturingFilterChain);
        //
        //////////////////

        final ServletRequest capturedServletRequest = extractCapturedServletRequest(capturingFilterChain);
        final ServletResponse capturedServletResponse = extractCapturedServletResponse(capturingFilterChain);
        final String expectedTxId = txIdExtractor.apply((HttpServletRequest) capturedServletRequest);

        assertRequestObjectHeaders(capturedServletRequest, expectedTxId);
        assertResponseObjectHeaders(capturedServletResponse, expectedTxId);
    }


    private void assertRequestObjectHeaders(ServletRequest request, String expectedTxId) {
        final HttpServletRequest httpServletRequest = (HttpServletRequest) request;

        assertThat(Collections.list(httpServletRequest.getHeaderNames()),
                containsInAnyOrder(equalToIgnoringCase(ECOMP_REQUEST_ID), equalToIgnoringCase(anotherHeader)));

        assertThat(httpServletRequest.getHeader(anotherHeader), is(anotherValue));

        assertThat(httpServletRequest.getHeader(ECOMP_REQUEST_ID), is(expectedTxId));
        assertThat(httpServletRequest.getHeader(mixedCaseHeader), is(expectedTxId));

        assertThat(UserUtils.getRequestId(httpServletRequest), is(expectedTxId));
        assertThat(UserUtils.getRequestId(httpServletRequest), is(not(emptyOrNullString())));
    }

    private void assertResponseObjectHeaders(ServletResponse response, String txId) {
        final String REQUEST_ID_HEADER_NAME_IN_RESPONSE = mixedCaseHeader + "-echo";
        final HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        assertThat("header " + REQUEST_ID_HEADER_NAME_IN_RESPONSE.toLowerCase() + " in response must be provided",
                httpServletResponse.getHeader(REQUEST_ID_HEADER_NAME_IN_RESPONSE), is(txId));
    }



    private HttpServletRequest createMockedHttpServletRequest(Map<String, String> requestHeaders) {
        HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class);
        requestHeaders.forEach((k, v) -> {
            Mockito.when(servletRequest.getHeader(argThat(equalToIgnoringCase(k)))).thenReturn(v);
            Mockito.when(servletRequest.getHeaders(argThat(equalToIgnoringCase(k)))).then(returnEnumerationAnswer(v));
        });
        Mockito.when(servletRequest.getHeaderNames()).then(returnEnumerationAnswer(requestHeaders.keySet()));
        return servletRequest;
    }

    private HttpServletResponse createMockedHttpServletResponse() {
        return new MockHttpServletResponse();
    }

    private static Answer<Enumeration<String>> returnEnumerationAnswer(String ... items) {
        return returnEnumerationAnswer(Arrays.asList(items));
    }

    private static Answer<Enumeration<String>> returnEnumerationAnswer(Collection<String> items) {
        return invocation -> Collections.enumeration(items);
    }

    private Function<HttpServletRequest, String> specificTxId(String someTxId) {
        return r -> someTxId;
    }

    private ServletRequest extractCapturedServletRequest(FilterChain capturingFilterChain) throws IOException, ServletException {
        ArgumentCaptor<ServletRequest> captor = ArgumentCaptor.forClass(ServletRequest.class);
        Mockito.verify(capturingFilterChain).doFilter(captor.capture(), any());
        return captor.getValue();
    }

    private ServletResponse extractCapturedServletResponse(FilterChain capturingFilterChain) throws IOException, ServletException {
        ArgumentCaptor<ServletResponse> captor = ArgumentCaptor.forClass(ServletResponse.class);
        Mockito.verify(capturingFilterChain).doFilter(any(), captor.capture());
        return captor.getValue();
    }

}
