/*
 * 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.junit.impl.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

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

import org.apache.sling.junit.Renderer;
import org.apache.sling.junit.RendererSelector;
import org.apache.sling.junit.RequestParser;
import org.apache.sling.junit.TestSelector;
import org.apache.sling.junit.TestsManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ServletProcessor {

    private final Logger log = LoggerFactory.getLogger(getClass());

    public static final String CSS = "junit.css";
    public static final String FORCE_RELOAD_PARAM = "forceReload";

    private final TestsManager testsManager;

    private final RendererSelector rendererSelector;

    public ServletProcessor(final TestsManager testsManager,
            final RendererSelector rendererSelector) {
        this.testsManager = testsManager;
        this.rendererSelector = rendererSelector;
    }

    /** Return sorted list of available tests
     * @param prefix optionally select only names that match this prefix
     */
    private List<String> getTestNames(TestSelector selector, boolean forceReload) {
        final List<String> result = new LinkedList<String>();
        if(forceReload) {
            log.debug("{} is true, clearing TestsManager caches", FORCE_RELOAD_PARAM);
        }
        result.addAll(testsManager.getTestNames(selector));
        Collections.sort(result);
        return result;
    }

    private void sendCss(HttpServletResponse response) throws IOException {
        final InputStream str = getClass().getResourceAsStream("/" + CSS);
        if(str == null) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, CSS);
        } else {
            response.setContentType("text/css");
            final OutputStream out = response.getOutputStream();
            final byte[] buffer = new byte[16384];
            int count = 0;
            while( (count = str.read(buffer)) > 0) {
                out.write(buffer, 0, count);
            }
            out.flush();
        }
    }

    private boolean getForceReloadOption(HttpServletRequest request) {
        final boolean forceReload = "true".equalsIgnoreCase(request.getParameter(FORCE_RELOAD_PARAM));
        log.debug("{} option is set to {}", FORCE_RELOAD_PARAM, forceReload);
        return forceReload;
    }

    /** GET request lists available tests */
    public void doGet(final HttpServletRequest request, final HttpServletResponse response, final String servletPath)
    throws ServletException, IOException {
        final boolean forceReload = getForceReloadOption(request);

        // Redirect to / if called without it, and serve CSS if requested
        {
            final String pi = request.getPathInfo();
            if(pi == null) {
                response.sendRedirect(request.getContextPath() + servletPath + "/");
            } else if(pi.endsWith(CSS)) {
                sendCss(response);
                return;
            }
        }

        final TestSelector selector = getTestSelector(request);
        final Renderer renderer = rendererSelector.getRenderer(selector);
        if(renderer == null) {
            throw new ServletException("No Renderer found for " + selector);
        }
        log.debug("GET request: {}", selector);

        renderer.setup(response, getClass().getSimpleName());
        renderer.info("info", "Test selector: " + selector);

        // Any test classes?
        final List<String> testNames = getTestNames(selector, forceReload);
        if(testNames.isEmpty()) {
            renderer.info(
                    "warning",
                    "No test classes found for selector " + selector
                    + ", check the requirements of the active " +
                    "TestsProvider services for how to supply tests."
                    );
        } else {
            try {
                testsManager.listTests(testNames, renderer);
                final String postPath = getTestExecutionPath(request, selector, renderer.getExtension());
                renderer.link("Execute these tests", postPath, "POST");
            } catch(Exception e) {
                throw new ServletException(e);
            }
        }
        renderer.cleanup();
    }

    /** POST request executes tests */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        final TestSelector selector = getTestSelector(request);
        final boolean forceReload = getForceReloadOption(request);
        log.info("POST request, executing tests: {}, {}={}",
                new Object[] { selector, FORCE_RELOAD_PARAM, forceReload});

        final Renderer renderer = rendererSelector.getRenderer(selector);
        if(renderer == null) {
            throw new ServletException("No Renderer found for " + selector);
        }
        renderer.setup(response, getClass().getSimpleName());

        final List<String> testNames = getTestNames(selector, forceReload);
        if(testNames.isEmpty()) {
            response.sendError(
                    HttpServletResponse.SC_NOT_FOUND,
                    "No tests found for " + selector);
        }
        try {
            testsManager.executeTests(testNames, renderer, selector);
        } catch(Exception e) {
            throw new ServletException(e);
        }

        renderer.cleanup();
    }

    /** Return a TestSelector for supplied request */
    private TestSelector getTestSelector(HttpServletRequest request) {
        return new RequestParser(getTestSelectionPath(request));
    }

    /** Return subpath to use for selecting tests */
    protected String getTestSelectionPath(HttpServletRequest request) {
        return request.getPathInfo();
    }

    /** Return path to which to POST to execute specified test */
    protected String getTestExecutionPath(HttpServletRequest request, TestSelector selector, String extension) {
    	String selectedTestMethodName = selector.getSelectedTestMethodName();
    	String methodStr = "";
    	if (selectedTestMethodName != null && !"".equals(selectedTestMethodName)) {
    		methodStr = "/" + selectedTestMethodName;
    	}
        return  "./"
        + selector.getTestSelectorString()
        + methodStr
        + "."
        + extension;
    }
}