/*
 * 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.launchpad.webapp.integrationtest;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.sling.commons.testing.integration.HttpTestBase;
import org.apache.sling.servlets.post.SlingPostConstants;


/** Test the {link ScriptHelper#include) functionality */
 public class IncludeTest extends HttpTestBase {

    private String nodeUrlA;
    private String testTextA;
    private String nodeUrlB;
    private String testTextB;
    private String nodeUrlC;
    private String nodeUrlD;
    private String nodeUrlE;
    private String scriptPath;
    private Set<String> toDelete = new HashSet<String>();

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        // Create the test nodes under a path that's specific to this class to
        // allow collisions
        final String url = HTTP_BASE_URL + "/" + getClass().getSimpleName() + "/" + System.currentTimeMillis() + SlingPostConstants.DEFAULT_CREATE_SUFFIX;
        final Map<String,String> props = new HashMap<String,String>();

        // Create two test nodes and store their paths
        testTextA = "Text A " + System.currentTimeMillis();
        props.put("text", testTextA);
        nodeUrlA = testClient.createNode(url, props);
        String pathToInclude = nodeUrlA.substring(HTTP_BASE_URL.length());

        // Node B stores the path of A, so that the test script can
        // include A when rendering B
        testTextB = "Text B " + System.currentTimeMillis();
        props.put("text", testTextB);
        props.put("pathToInclude", pathToInclude);
        nodeUrlB = testClient.createNode(url, props);

        // Node E is like B but with an extension on the include path
        props.put("pathToInclude", pathToInclude + ".html");
        nodeUrlE = testClient.createNode(url, props);

        // Node C is used for the infinite loop detection test
        props.remove("pathToInclude");
        props.put("testInfiniteLoop","true");
        nodeUrlC = testClient.createNode(url, props);

        // Node D is used for the "force resource type" test
        final String forcedResourceType = getClass().getSimpleName() + "/" + System.currentTimeMillis();
        props.remove("testInfiniteLoop");
        props.put("forceResourceType", forcedResourceType);
        props.put("pathToInclude", pathToInclude);
        nodeUrlD = testClient.createNode(url, props);

        // Script for forced resource type
        scriptPath = "/apps/" + forcedResourceType;
        testClient.mkdirs(WEBDAV_BASE_URL, scriptPath);
        toDelete.add(uploadTestScript(scriptPath,"include-forced.esp","html.esp"));

        // The main rendering script goes under /apps in the repository
        scriptPath = "/apps/nt/unstructured";
        testClient.mkdirs(WEBDAV_BASE_URL, scriptPath);
        toDelete.add(uploadTestScript(scriptPath,"include-test.esp","html.esp"));
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
        for(String script : toDelete) {
            testClient.delete(script);
        }
    }

    public void testWithoutInclude() throws IOException {
        final String content = getContent(nodeUrlA + ".html", CONTENT_TYPE_HTML);
        assertTrue("Content includes ESP marker",content.contains("ESP template"));
        assertTrue("Content contains formatted test text",content.contains("<p class=\"main\">" + testTextA + "</p>"));
        assertFalse("Nothing has been included",content.contains("<p>Including"));
        assertNoIncludeRequestAttributes(content);
    }

    public void testWithInclude() throws IOException {
        final String content = getContent(nodeUrlB + ".html", CONTENT_TYPE_HTML);
        assertTrue("Content includes ESP marker",content.contains("ESP template"));
        assertTrue("Content contains formatted test text",content.contains("<p class=\"main\">" + testTextB + "</p>"));
        assertTrue("Include has been used",content.contains("<p>Including"));
        assertTrue("Text of node A is included (" + content + ")",content.contains(testTextA));
        assertIncludeRequestAttributes(content);
    }

    public void testWithIncludeAndExtension() throws IOException {
        final String content = getContent(nodeUrlE + ".html", CONTENT_TYPE_HTML);
        assertTrue("Content includes ESP marker",content.contains("ESP template"));
        assertTrue("Content contains formatted test text",content.contains("<p class=\"main\">" + testTextB + "</p>"));
        assertTrue("Include has been used",content.contains("<p>Including"));
        assertTrue("Text of node A is included (" + content + ")",content.contains(testTextA));
        assertIncludeRequestAttributes(content);
    }

    public void testInfiniteLoopDetection() throws IOException {
        // Node C has a property that causes an infinite include loop,
        // Sling must indicate the problem in its response
        final GetMethod get = new GetMethod(nodeUrlC + ".html");
        httpClient.executeMethod(get);
        final String content = get.getResponseBodyAsString();
        assertTrue(
            "Response contains infinite loop error message",
            content.contains("org.apache.sling.api.request.RecursionTooDeepException"));

        // TODO: SLING-515, status is 500 when running the tests as part of the maven build
        // but 200 if running tests against a separate instance started with mvn jetty:run
        // final int status = get.getStatusCode();
        // assertEquals("Status is 500 for infinite loop",HttpServletResponse.SC_INTERNAL_SERVER_ERROR, status);
    }

    public void testForcedResourceType() throws IOException {
        final String content = getContent(nodeUrlD + ".html", CONTENT_TYPE_HTML);
        assertTrue("Content includes ESP marker",content.contains("ESP template"));
        assertTrue("Content contains formatted test text",content.contains("<p class=\"main\">" + testTextB + "</p>"));
        assertTrue("Include has been used",content.contains("<p>Including"));
        assertTrue("Text of node A is included (" + content + ")",content.contains(testTextA));
        assertTrue("Resource type has been forced (" + content + ")",content.contains("Forced resource type:" + testTextA));
        assertIncludeRequestAttributes(content);
    }

    // also used by ForwardTest
    static void assertIncludeRequestAttributes(final String content) {
        assertIncludeRequestAttributes(content, "");
    }

    // also used by ForwardTest
    static void assertNoIncludeRequestAttributes(final String content) {
        assertIncludeRequestAttributes(content, "no");
    }

    private static void assertIncludeRequestAttributes(final String content, final String tag) {

        // Servlet API attributes set on include
        // except javax.servlet.include.query_string which not be set in request

        assertRequestAttribute(content, tag,
            "javax.servlet.include.request_uri");
        assertRequestAttribute(content, tag,
            "javax.servlet.include.context_path");
        assertRequestAttribute(content, tag,
            "javax.servlet.include.servlet_path");
        assertRequestAttribute(content, tag, "javax.servlet.include.path_info");
        assertRequestAttribute(content, tag,
            "javax.servlet.include.request_uri");
        assertRequestAttribute(content, tag,
            "javax.servlet.include.request_uri");
        assertRequestAttribute(content, tag,
            "org.apache.sling.api.include.servlet");
        assertRequestAttribute(content, tag,
            "org.apache.sling.api.include.resource");
        assertRequestAttribute(content, tag,
            "org.apache.sling.api.include.request_path_info");
    }

    private static void assertRequestAttribute(final String content,
            final String tag,
            final String attrName) {
        assertTrue("Expected content contains '-" + tag + "-" + attrName + "-'",
            content.contains("-" + tag + "-" + attrName + "-"));
    }
}
