/*
 * 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.auth.form.impl;

import static org.easymock.EasyMock.cmpEq;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;

import java.io.File;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.sling.api.auth.Authenticator;
import org.apache.sling.auth.core.spi.AuthenticationInfo;
import org.apache.sling.auth.core.spi.DefaultAuthenticationFeedbackHandler;
import org.hamcrest.Description;
import org.hamcrest.core.StringStartsWith;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.api.Action;
import org.jmock.api.Invocation;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.osgi.framework.BundleContext;
import org.powermock.api.easymock.PowerMock;
import org.powermock.api.support.membermodification.MemberMatcher;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(FormAuthenticationHandler.class)
@PowerMockIgnore("jdk.internal.reflect.*")
public class FormAuthenticationHandlerTest {

    @Test public void test_getTokenFile() {
        final File root = new File("bundle999").getAbsoluteFile();
        final SlingHomeAction slingHome = new SlingHomeAction();
        slingHome.setSlingHome(new File("sling").getAbsolutePath());

        Mockery context = new Mockery();
        final BundleContext bundleContext = context.mock(BundleContext.class);

        context.checking(new Expectations() {
            {
                // mock access to sling.home framework property
                allowing(bundleContext).getProperty("sling.home");
                will(slingHome);

                // mock no data file support with file names starting with sl
                allowing(bundleContext).getDataFile(
                    with(new StringStartsWith("sl")));
                will(returnValue(null));

                // mock data file support for any other name
                allowing(bundleContext).getDataFile(with(any(String.class)));
                will(new RVA(root));
            }
        });

        final FormAuthenticationHandler handler = new FormAuthenticationHandler();

        // test files relative to bundle context
        File relFile0 = handler.getTokenFile("", bundleContext);
        assertEquals(root, relFile0);

        String relName1 = "rel/path";
        File relFile1 = handler.getTokenFile(relName1, bundleContext);
        assertEquals(new File(root, relName1), relFile1);

        // test file relative to sling.home if no data file support
        String relName2 = "sl/rel_to_sling.home";
        File relFile2 = handler.getTokenFile(relName2, bundleContext);
        assertEquals(new File(slingHome.getSlingHome(), relName2), relFile2);

        // test file relative to current working directory
        String relName3 = "sl/test";
        slingHome.setSlingHome(null);
        File relFile3 = handler.getTokenFile(relName3, bundleContext);
        assertEquals(new File(relName3).getAbsoluteFile(), relFile3);

        // test absolute file return
        File absFile = new File("test").getAbsoluteFile();
        File absFile0 = handler.getTokenFile(absFile.getPath(), bundleContext);
        assertEquals(absFile, absFile0);
    }

    @Test public void test_getUserid() {
        final FormAuthenticationHandler handler = new FormAuthenticationHandler();
        assertEquals(null, handler.getUserId(null));
        assertEquals(null, handler.getUserId(""));
        assertEquals(null, handler.getUserId("field0"));
        assertEquals(null, handler.getUserId("field0@field1"));
        assertEquals("field3", handler.getUserId("field0@field1@field3"));
        assertEquals("field3@field4", handler.getUserId("field0@field1@field3@field4"));
    }

    /**
     * Test for SLING-3443 Parameter based redirection should only handle relative paths
     * @throws Exception PowerMock.expectPrivate throws Exception and UrlEncoder.encode
     *                          throws UnsupportedEncodingException
     * @since 1.0.6
     */
    @Test public void testRedirectionAfterLogin() throws Exception {
        // Create mocks
        final HttpServletRequest request = createMock(HttpServletRequest.class);
        final HttpServletResponse response = createMock(HttpServletResponse.class);
        final AuthenticationInfo authenticationInfo = createMock(AuthenticationInfo.class);

        // Use PowerMock to mock private method
        final String methodName = "refreshAuthData";
        final FormAuthenticationHandler authenticationHandler = PowerMock.createPartialMock(FormAuthenticationHandler.class,
                methodName);
        final Method[] methods = MemberMatcher.methods(FormAuthenticationHandler.class, methodName);
        PowerMock.expectPrivate(authenticationHandler, methods[0], request, response, authenticationInfo);

        // Mock the static method since we are just unit testing the authentication succeeded flow
        PowerMock.mockStatic(DefaultAuthenticationFeedbackHandler.class);
        expect(DefaultAuthenticationFeedbackHandler.handleRedirect(request, response)).andReturn(false);

        // Mocks the Authenticator.LOGIN_RESOURCE attribute
        final String url = "http://www.blah.com";
        expect(request.getAttribute(Authenticator.LOGIN_RESOURCE)).andReturn(url);

        // Mocks the HttpServletRequest and HttpServletResponse object
        expect(request.getMethod()).andReturn("POST");
        expect(request.getRequestURI()).andReturn("http://blah/blah/j_security_check");
        String contextPath = "/blah";
        expect(request.getContextPath()).andReturn(contextPath).anyTimes();
        expect(response.isCommitted()).andReturn(false);

        // Mocking method with void return type
        response.resetBuffer();
        expectLastCall().once();

        // The request should be redirected to the context root rather than the
        // passing the parameter directly
        response.sendRedirect(cmpEq(contextPath));

        // Replay the mocks
        replay(request);
        replay(response);
        replay(authenticationInfo);
        replay(authenticationHandler);

        // Test the method
        authenticationHandler.authenticationSucceeded(request, response, authenticationInfo);

        // Verify mocks
        verify(request, response, authenticationInfo, authenticationHandler);
    }

    /**
     * The <code>RVA</code> action returns a file relative to some root file as
     * requested by the first parameter of the invocation, expecting the first
     * parameter to be a string.
     */
    private static class RVA implements Action {

        private final File root;

        RVA(final File root) {
            this.root = root;
        }

        public Object invoke(Invocation invocation) throws Throwable {
            String data = (String) invocation.getParameter(0);
            if (data.startsWith("/")) {
                data = data.substring(1);
            }
            return new File(root, data);
        }

        public void describeTo(Description description) {
            description.appendText("returns new File(root, arg0)");
        }
    }

    /**
     * The <code>SlingHomeAction</code> action returns the current value of the
     * <code>slingHome</code> field on all invocations
     */
    private static class SlingHomeAction implements Action {
        private String slingHome;

        public void setSlingHome(String slingHome) {
            this.slingHome = slingHome;
        }

        public String getSlingHome() {
            return slingHome;
        }

        public Object invoke(Invocation invocation) throws Throwable {
            return slingHome;
        }

        public void describeTo(Description description) {
            description.appendText("returns " + slingHome);
        }
    }
}
