/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
package org.apache.sling.servlethelpers;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.CharEncoding;
import org.apache.sling.api.request.RequestDispatcherOptions;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.HttpConstants;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MockSlingHttpServletRequestTest {

    @Mock
    private ResourceResolver resourceResolver;
    @Mock
    private Resource resource;

    private MockSlingHttpServletRequest request;

    @Before
    public void setUp() throws Exception {
        request = new MockSlingHttpServletRequest(resourceResolver);
    }
    
    @Test
    public void testResourceResolver() {
        assertSame(resourceResolver, request.getResourceResolver());
    }

    @Test
    public void testDefaultResourceResolver() {
        assertNotNull(request.getResourceResolver());
    }

    @Test
    public void testSession() {
        HttpSession session = request.getSession(false);
        assertNull(session);
        session = request.getSession();
        assertNotNull(session);
    }

    @Test
    public void testPathInfo() {
        MockRequestPathInfo requestPathInfo = (MockRequestPathInfo) request.getRequestPathInfo();
        requestPathInfo.setResourcePath("/content/resource");
        requestPathInfo.setExtension("html");
        requestPathInfo.setSelectorString("a1.a2");
        requestPathInfo.setSuffix("/content/another/resource.html");

        assertEquals("/content/resource.a1.a2.html/content/another/resource.html", request.getPathInfo());

        requestPathInfo.setSelectorString(null);

        assertEquals("/content/resource.html/content/another/resource.html", request.getPathInfo());

        requestPathInfo.setSuffix(null);

        assertEquals("/content/resource.html", request.getPathInfo());

        requestPathInfo.setResourcePath(null);

        assertNull(request.getPathInfo());
    }

    @Test
    public void testRequestUri() {
        MockRequestPathInfo requestPathInfo = (MockRequestPathInfo) request.getRequestPathInfo();
        requestPathInfo.setResourcePath("/content/resource");
        requestPathInfo.setExtension("html");
        requestPathInfo.setSelectorString("a1.a2");
        requestPathInfo.setSuffix("/content/another/resource.html");

        assertEquals("/content/resource.a1.a2.html/content/another/resource.html", request.getRequestURI());

        request.setServletPath("/my");

        assertEquals("/my/content/resource.a1.a2.html/content/another/resource.html", request.getRequestURI());
    }

    @Test
    public void testRequestUrl() {
        MockRequestPathInfo requestPathInfo = (MockRequestPathInfo) request.getRequestPathInfo();
        requestPathInfo.setResourcePath("/content/resource");
        requestPathInfo.setExtension("html");

        assertEquals("http://localhost/content/resource.html", request.getRequestURL().toString());

        request.setServerPort(8080);

        assertEquals("http://localhost:8080/content/resource.html", request.getRequestURL().toString());

        request.setScheme("https");
        request.setServerPort(443);

        assertEquals("https://localhost/content/resource.html", request.getRequestURL().toString());

        request.setServerPort(8443);

        assertEquals("https://localhost:8443/content/resource.html", request.getRequestURL().toString());
    }

    @Test
    public void testRequestPathInfo() {
        assertNotNull(request.getRequestPathInfo());
    }

    @Test
    public void testAttributes() {
        request.setAttribute("attr1", "value1");
        assertTrue(request.getAttributeNames().hasMoreElements());
        assertEquals("value1", request.getAttribute("attr1"));
        request.removeAttribute("attr1");
        assertFalse(request.getAttributeNames().hasMoreElements());
    }

    @Test
    public void testResource() {
        assertNull(request.getResource());
        request.setResource(resource);
        assertSame(resource, request.getResource());
    }

    @Test
    public void testContextPath() {
        assertNull(request.getContextPath());
        request.setContextPath("/ctx");
        assertEquals("/ctx", request.getContextPath());
    }

    @Test
    public void testLocale() {
        assertEquals(Locale.US, request.getLocale());
        request.setLocale(Locale.GERMAN);
        assertEquals(Locale.GERMAN, request.getLocale());
    }

    @Test
    public void testQueryString() throws UnsupportedEncodingException {
        assertNull(request.getQueryString());
        assertEquals(0, request.getParameterMap().size());
        assertFalse(request.getParameterNames().hasMoreElements());

        request.setQueryString("param1=123&param2=" + URLEncoder.encode("äöüß€!:!", CharEncoding.UTF_8)
                + "&param3=a&param3=b");

        assertNotNull(request.getQueryString());
        assertEquals(3, request.getParameterMap().size());
        assertTrue(request.getParameterNames().hasMoreElements());
        assertEquals("123", request.getParameter("param1"));
        assertEquals("äöüß€!:!", request.getParameter("param2"));
        assertArrayEquals(new String[] { "a", "b" }, request.getParameterValues("param3"));

        Map<String, Object> paramMap = new LinkedHashMap<String, Object>();
        paramMap.put("p1", "a");
        paramMap.put("p2", new String[] { "b", "c" });
        paramMap.put("p3", null);
        paramMap.put("p4", new String[] { null });
        paramMap.put("p5", 22);
        request.setParameterMap(paramMap);

        assertEquals("p1=a&p2=b&p2=c&p4=&p5=22", request.getQueryString());
    }

    @Test
    public void testSchemeSecure() {
        assertEquals("http", request.getScheme());
        assertFalse(request.isSecure());

        request.setScheme("https");
        assertEquals("https", request.getScheme());
        assertTrue(request.isSecure());
    }

    @Test
    public void testServerNamePort() {
        assertEquals("localhost", request.getServerName());
        assertEquals(80, request.getServerPort());

        request.setServerName("myhost");
        request.setServerPort(12345);
        assertEquals("myhost", request.getServerName());
        assertEquals(12345, request.getServerPort());
    }

    @Test
    public void testMethod() {
        assertEquals(HttpConstants.METHOD_GET, request.getMethod());

        request.setMethod(HttpConstants.METHOD_POST);
        assertEquals(HttpConstants.METHOD_POST, request.getMethod());
    }

    @Test
    public void testHeaders() {
        assertFalse(request.getHeaderNames().hasMoreElements());

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MILLISECOND, 0);
        long dateValue = calendar.getTimeInMillis();

        request.addHeader("header1", "value1");
        request.addIntHeader("header2", 5);
        request.addDateHeader("header3", dateValue);

        assertEquals("value1", request.getHeader("Header1"));
        assertEquals(5, request.getIntHeader("headeR2"));
        assertEquals(dateValue, request.getDateHeader("header3"));

        request.setHeader("header1", "value2");
        request.addIntHeader("Header2", 10);

        Enumeration<String> header1Values = request.getHeaders("header1");
        assertEquals("value2", header1Values.nextElement());
        assertFalse(header1Values.hasMoreElements());

        Enumeration<String> header2Values = request.getHeaders("header2");
        assertEquals("5", header2Values.nextElement());
        assertEquals("10", header2Values.nextElement());
        assertFalse(header2Values.hasMoreElements());
    }

    @Test(expected = IllegalArgumentException.class)
    public void testInvalidDateHeader() {
        request.addHeader("header1", "thisIsNotADate");
        // make sure IllegalArgumentException is thrown as defined by the HttpServletRequest API
        request.getDateHeader("header1");
    }

    @Test
    public void testCookies() {
        assertNull(request.getCookies());

        request.addCookie(new Cookie("cookie1", "value1"));
        request.addCookie(new Cookie("cookie2", "value2"));

        assertEquals("value1", request.getCookie("cookie1").getValue());

        Cookie[] cookies = request.getCookies();
        assertEquals(2, cookies.length);
        assertEquals("value1", cookies[0].getValue());
        assertEquals("value2", cookies[1].getValue());
    }
    
    @Test
    public void testDefaultResourceBundle() {
        ResourceBundle bundle = request.getResourceBundle(Locale.US);
        assertNotNull(bundle);
        assertFalse(bundle.getKeys().hasMoreElements());
    }

    @Test
    public void testRequestParameter() throws Exception {
        request.setQueryString("param1=123&param2=" + URLEncoder.encode("äöüß€!:!", CharEncoding.UTF_8)
                + "&param3=a&param3=b");

        assertEquals(3, request.getRequestParameterMap().size());
        assertEquals(4, request.getRequestParameterList().size());
        assertEquals("123", request.getRequestParameter("param1").getString());
        assertEquals("äöüß€!:!", request.getRequestParameter("param2").getString());
        assertEquals("a",request.getRequestParameters("param3")[0].getString());
        assertEquals("b",request.getRequestParameters("param3")[1].getString());

        assertNull(request.getRequestParameter("unknown"));
        assertNull(request.getRequestParameters("unknown"));

        assertEquals("param1", ((MockRequestParameter)request.getRequestParameter("param1")).getName());
    }

    @Test
    public void testFormRequestParameters() throws Exception {
    	request.addRequestParameter("param1", "value1");
    	request.addRequestParameter("param2", "value2".getBytes("UTF-8"), "application/xml");
    	request.addRequestParameter("param3", "value3".getBytes("UTF-8"), "application/json", "param3.json");
    	request.addRequestParameter("param4", "value4a".getBytes("UTF-8"), "application/xml");
    	request.addRequestParameter("param4", "value4b".getBytes("UTF-8"), "application/json");
    	
    	RequestParameter param1 = request.getRequestParameter("param1");
    	assertEquals("value1", param1.getString());
    	assertArrayEquals("value1".getBytes(), param1.get());
    	assertEquals("text/plain", param1.getContentType());
    	assertArrayEquals("value1".getBytes(), param1.get());
    	
    	RequestParameter param2 = request.getRequestParameter("param2");
    	assertEquals("value2", param2.getString());
    	assertEquals("application/xml", param2.getContentType());
    	assertArrayEquals("value2".getBytes(), param2.get());
    	
    	RequestParameter param3 = request.getRequestParameter("param3");
    	assertEquals("value3", param3.getString());
    	assertEquals("application/json", param3.getContentType());
    	assertArrayEquals("value3".getBytes(), param3.get());
    	assertEquals("param3.json", param3.getFileName());
    	
    	RequestParameter param4 = request.getRequestParameter("param4");
    	assertEquals("value4a", param4.getString());
    	assertEquals("application/xml", param4.getContentType());
    	assertArrayEquals("value4a".getBytes(), param4.get());

    	RequestParameter[] param4array = request.getRequestParameters("param4");
    	assertEquals(2, param4array.length);
    	assertEquals("value4a", param4array[0].getString());
    	assertEquals("value4b", param4array[1].getString());
    	assertEquals("application/xml", param4array[0].getContentType());
    	assertEquals("application/json", param4array[1].getContentType());
    	assertArrayEquals("value4a".getBytes(), param4array[0].get());
    	assertArrayEquals("value4b".getBytes(), param4array[1].get());
    	
    }

    @Test
    public void testContentTypeCharset() throws Exception {
        assertNull(request.getContentType());
        assertNull(request.getCharacterEncoding());

        request.setContentType("image/gif");
        assertEquals("image/gif", request.getContentType());
        assertNull(request.getCharacterEncoding());
        
        request.setContentType("text/plain;charset=UTF-8");
        assertEquals("text/plain;charset=UTF-8", request.getContentType());
        assertEquals(CharEncoding.UTF_8, request.getCharacterEncoding());
        
        request.setCharacterEncoding(CharEncoding.ISO_8859_1);
        assertEquals("text/plain;charset=ISO-8859-1", request.getContentType());
        assertEquals(CharEncoding.ISO_8859_1, request.getCharacterEncoding());
    }

    @Test
    public void testContent() throws Exception {
        assertEquals(0, request.getContentLength());
        assertNotNull(request.getInputStream());
        assertArrayEquals(new byte[0], IOUtils.toByteArray(request.getInputStream()));
        
        byte[] data = new byte[] { 0x01,0x02,0x03 };
        request.setContent(data);

        assertEquals(data.length, request.getContentLength());
        assertArrayEquals(data, IOUtils.toByteArray(request.getInputStream()));
    }

    @Test
    public void testContentFromReader() throws Exception {
        Charset utf8 = Charset.forName("UTF-8");
        request.setContent("hello".getBytes(utf8));
        assertEquals(5, request.getContentLength());
        BufferedReader reader = request.getReader();
        String content = IOUtils.toString(reader);
        assertEquals("hello", content);
    }

    @Test
    public void testGetReaderAfterGetInputStream() {
        boolean thrown = false;
        request.getInputStream();
        try {
            request.getReader();
        } catch (IllegalStateException e) {
            thrown = true;
        }
        assertTrue(thrown);
    }

    @Test
    public void testGetInputStreamAfterGetReader() {
        boolean thrown = false;
        request.getReader();
        try {
            request.getInputStream();
        } catch (IllegalStateException e) {
            thrown = true;
        }
        assertTrue(thrown);
    }


    @Test
    public void testGetRequestDispatcher() {
        MockRequestDispatcherFactory requestDispatcherFactory = mock(MockRequestDispatcherFactory.class);
        RequestDispatcher requestDispatcher = mock(RequestDispatcher.class);
        when(requestDispatcherFactory.getRequestDispatcher(any(Resource.class), any())).thenReturn(requestDispatcher);
        when(requestDispatcherFactory.getRequestDispatcher(any(String.class), any())).thenReturn(requestDispatcher);
        
        request.setRequestDispatcherFactory(requestDispatcherFactory);
        
        assertSame(requestDispatcher, request.getRequestDispatcher("/path"));
        assertSame(requestDispatcher, request.getRequestDispatcher("/path", new RequestDispatcherOptions()));
        assertSame(requestDispatcher, request.getRequestDispatcher(resource));
        assertSame(requestDispatcher, request.getRequestDispatcher(resource, new RequestDispatcherOptions()));
    }
    
    @Test(expected = IllegalStateException.class)
    public void testGetRequestDispatcherWithoutFactory() {
        request.getRequestDispatcher("/path");
    }
    
    @Test
    public void testGetRemoteUser() {
        assertNull(null, request.getRemoteUser());
        
        request.setRemoteUser("admin");
        assertEquals("admin", request.getRemoteUser());
    }

    @Test
    public void testGetRemoteAddr() throws Exception {
        assertNull(null, request.getRemoteAddr());
        
        request.setRemoteAddr("1.2.3.4");
        assertEquals("1.2.3.4", request.getRemoteAddr());
    }

    @Test
    public void testGetRemoteHost() throws Exception {
        assertNull(null, request.getRemoteHost());
        
        request.setRemoteHost("host1");
        assertEquals("host1", request.getRemoteHost());
    }

    @Test
    public void testGetRemotePort() throws Exception {
        assertEquals(0, request.getRemotePort());
        
        request.setRemotePort(1234);
        assertEquals(1234, request.getRemotePort());
    }

    @Test
    public void testServletPathWithPathInfo() throws Exception {
        request.setServletPath("/my/path");
        request.setPathInfo("/myinfo");;

        assertEquals("/my/path", request.getServletPath());
        assertEquals("/myinfo", request.getPathInfo());
    }

    @Test
    public void testServletPathWithOutPathInfo() throws Exception {
        request.setServletPath("/my/path");

        assertEquals("/my/path", request.getServletPath());
        assertNull(request.getPathInfo());
    }

    @Test
    public void testGetSuffixResource() {
        assertNull(request.getRequestPathInfo().getSuffixResource());
        
        ((MockRequestPathInfo)request.getRequestPathInfo()).setSuffix("/suffix");
        Resource resource = mock(Resource.class);
        when(resourceResolver.getResource("/suffix")).thenReturn(resource);
        
        assertSame(resource, request.getRequestPathInfo().getSuffixResource());
    }

    
}
