/**
 * 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.cxf.dosgi.common.httpservice;

import java.io.PrintWriter;
import java.net.URL;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.easymock.EasyMock;
import org.junit.Assert;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpContext;

import junit.framework.TestCase;

@SuppressWarnings({
    "unchecked", "rawtypes"
   })
public class SecurityDelegatingHttpContextTest extends TestCase {

    protected HttpContext defaultHttpContext;
    protected SecurityDelegatingHttpContext httpContext;
    protected CommitResponseFilter commitFilter;
    protected DoNothingFilter doNothingFilter;
    protected AccessDeniedFilter accessDeniedFilter;
    protected String mimeType;
    protected URL url; // does not need to exist

    @Override
    public void setUp() throws Exception {
        mimeType = "text/xml";
        url = new URL("file:test.xml"); // does not need to exist

        // Sample filters
        commitFilter = new CommitResponseFilter();
        doNothingFilter = new DoNothingFilter();
        accessDeniedFilter = new AccessDeniedFilter();

        // Mock up the default http context
        defaultHttpContext = EasyMock.createNiceMock(HttpContext.class);
        EasyMock.expect(defaultHttpContext.getMimeType((String)EasyMock.anyObject())).andReturn(mimeType);
        EasyMock.expect(defaultHttpContext.getResource((String)EasyMock.anyObject())).andReturn(url);
        EasyMock.replay(defaultHttpContext);
    }

    public void testFilterRequired() throws Exception {
        // Mock up the service references
        ServiceReference[] serviceReferences = {};

        // Mock up the bundle context
        BundleContext bundleContext = EasyMock.createNiceMock(BundleContext.class);
        EasyMock.expect(bundleContext.getServiceReferences(Filter.class.getName(),
                                                           "(org.apache.cxf.httpservice.filter=true)"))
            .andReturn(serviceReferences);
        EasyMock.replay(bundleContext);

        // Set up the secure http context
        httpContext = new SecurityDelegatingHttpContext(bundleContext, defaultHttpContext);
        httpContext.requireFilter = true;

        // Ensure that the httpContext doesn't allow the request to be processed, since there are no registered servlet
        // filters
        HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
        EasyMock.replay(request);
        HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
        EasyMock.replay(response);
        boolean requestAllowed = httpContext.handleSecurity(request, response);
        Assert.assertFalse(requestAllowed);

        // Ensure that the httpContext returns true if there is no requirement for registered servlet filters
        httpContext.requireFilter = false;
        requestAllowed = httpContext.handleSecurity(request, response);
        Assert.assertTrue(requestAllowed);
    }

    public void testSingleCommitFilter() throws Exception {
        // Mock up the service references
        ServiceReference filterReference = EasyMock.createNiceMock(ServiceReference.class);
        EasyMock.replay(filterReference);
        ServiceReference[] serviceReferences = {filterReference};

        // Mock up the bundle context
        BundleContext bundleContext = EasyMock.createNiceMock(BundleContext.class);
        EasyMock.expect(bundleContext.getServiceReferences((String)EasyMock.anyObject(), (String)EasyMock.anyObject()))
            .andReturn(serviceReferences);
        EasyMock.expect(bundleContext.getService((ServiceReference)EasyMock.anyObject())).andReturn(commitFilter);
        EasyMock.replay(bundleContext);

        // Set up the secure http context
        httpContext = new SecurityDelegatingHttpContext(bundleContext, defaultHttpContext);

        // Ensure that the httpContext returns false, since the filter has committed the response
        HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
        EasyMock.replay(request);
        HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
        EasyMock.expect(response.isCommitted()).andReturn(false); // the first call checks to see whether to invoke the
                                                                  // filter
        EasyMock.expect(response.isCommitted()).andReturn(true); // the second is called to determine the handleSecurity
                                                                 // return value
        EasyMock.expect(response.getWriter()).andReturn(new PrintWriter(System.out));
        EasyMock.replay(response);
        Assert.assertFalse(httpContext.handleSecurity(request, response));

        // Ensure that the appropriate filters were called
        Assert.assertTrue(commitFilter.called);
        Assert.assertFalse(doNothingFilter.called);
        Assert.assertFalse(accessDeniedFilter.called);
    }

    public void testFilterChain() throws Exception {
        // Mock up the service references
        ServiceReference filterReference = EasyMock.createNiceMock(ServiceReference.class);
        EasyMock.replay(filterReference);
        ServiceReference[] serviceReferences = {filterReference, filterReference};

        // Mock up the bundle context
        BundleContext bundleContext = EasyMock.createNiceMock(BundleContext.class);
        EasyMock.expect(bundleContext.getServiceReferences((String)EasyMock.anyObject(), (String)EasyMock.anyObject()))
            .andReturn(serviceReferences);
        EasyMock.expect(bundleContext.getService((ServiceReference)EasyMock.anyObject())).andReturn(doNothingFilter);
        EasyMock.expect(bundleContext.getService((ServiceReference)EasyMock.anyObject())).andReturn(commitFilter);
        EasyMock.replay(bundleContext);

        // Set up the secure http context
        httpContext = new SecurityDelegatingHttpContext(bundleContext, defaultHttpContext);

        // Ensure that the httpContext returns false, since the filter has committed the response
        HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
        EasyMock.replay(request);
        HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
        EasyMock.expect(response.isCommitted()).andReturn(false); // doNothingFilter should not commit the response
        EasyMock.expect(response.getWriter()).andReturn(new PrintWriter(System.out));
        EasyMock.expect(response.isCommitted()).andReturn(false);
        EasyMock.expect(response.isCommitted()).andReturn(true); // the commit filter indicating that it committed the
                                                                 // response
        EasyMock.replay(response);
        Assert.assertFalse(httpContext.handleSecurity(request, response));

        // Ensure that the appropriate filters were called
        Assert.assertTrue(doNothingFilter.called);
        Assert.assertTrue(commitFilter.called);
        Assert.assertFalse(accessDeniedFilter.called);
    }

    public void testAllowRequest() throws Exception {
        // Mock up the service references
        ServiceReference filterReference = EasyMock.createNiceMock(ServiceReference.class);
        EasyMock.replay(filterReference);
        ServiceReference[] serviceReferences = {filterReference};

        // Mock up the bundle context
        BundleContext bundleContext = EasyMock.createNiceMock(BundleContext.class);
        EasyMock.expect(bundleContext.getServiceReferences((String)EasyMock.anyObject(), (String)EasyMock.anyObject()))
            .andReturn(serviceReferences);
        EasyMock.expect(bundleContext.getService((ServiceReference)EasyMock.anyObject())).andReturn(doNothingFilter);
        EasyMock.replay(bundleContext);

        // Set up the secure http context
        httpContext = new SecurityDelegatingHttpContext(bundleContext, defaultHttpContext);

        // Ensure that the httpContext returns true, since the filter has not committed the response
        HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
        EasyMock.replay(request);
        HttpServletResponse response = EasyMock.createNiceMock(HttpServletResponse.class);
        EasyMock.expect(response.isCommitted()).andReturn(false);
        EasyMock.replay(response);
        Assert.assertTrue(httpContext.handleSecurity(request, response));

        // Ensure that the appropriate filters were called
        Assert.assertTrue(doNothingFilter.called);
        Assert.assertFalse(commitFilter.called);
        Assert.assertFalse(accessDeniedFilter.called);
    }

    public void testDelegation() {
        BundleContext bundleContext = EasyMock.createNiceMock(BundleContext.class);
        EasyMock.replay(bundleContext);

        // Set up the secure http context
        httpContext = new SecurityDelegatingHttpContext(bundleContext, defaultHttpContext);

        // Ensure that it delegates non-security calls to the wrapped implementation (in this case, the mock)
        Assert.assertEquals(mimeType, httpContext.getMimeType(""));
        Assert.assertEquals(url, httpContext.getResource(""));
    }
}

class CommitResponseFilter implements Filter {

    boolean called;

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws java.io.IOException {
        called = true;
        response.getWriter().write("committing the response");
    }
}

class DoNothingFilter implements Filter {

    boolean called;

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws java.io.IOException, javax.servlet.ServletException {
        called = true;
        chain.doFilter(request, response);
    }
}

class AccessDeniedFilter implements Filter {

    boolean called;

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws java.io.IOException {
        called = true;
        ((HttpServletResponse)response).sendError(HttpServletResponse.SC_FORBIDDEN);
    }
}
