/*
 * 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.servlets.get.impl;

import java.util.Collections;
import java.util.HashMap;

import javax.servlet.http.HttpServletResponse;

import junit.framework.TestCase;

import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.apache.sling.commons.testing.sling.MockResourceResolver;
import org.apache.sling.commons.testing.sling.MockSlingHttpServletRequest;

public class RedirectServletTest extends TestCase {

    static final String TEST_SCHEME = "http";

    static final String TEST_HOST = "the.host.any";

    static final int TEST_PORT = 80;

    static final String TEST_PREFIX = TEST_SCHEME + "://" + TEST_HOST;

    public void testToAbsoluteURI() {
        final String http = "http";
        final String https = "https";
        final String scheme = "test";
        final String host = TEST_HOST;
        final int port80 = 80;
        final int port443 = 443;
        final int portAny = 9999;
        final int portNone = -1;
        final String target = "/target";

        // regular building without default ports
        assertEquals(http + "://" + host + ":" + portAny + target,
                RedirectServlet.toAbsoluteUri(http, host, portAny, target));
        assertEquals(https + "://" + host + ":" + portAny + target,
                RedirectServlet.toAbsoluteUri(https, host, portAny, target));
        assertEquals(scheme + "://" + host + ":" + portAny + target,
                RedirectServlet.toAbsoluteUri(scheme, host, portAny, target));

        // building with default ports
        assertEquals(http + "://" + host + target, RedirectServlet.toAbsoluteUri(http, host, port80, target));
        assertEquals(https + "://" + host + target, RedirectServlet.toAbsoluteUri(https, host, port443, target));
        assertEquals(scheme + "://" + host + ":" + port80 + target,
                RedirectServlet.toAbsoluteUri(scheme, host, port80, target));

        // building without ports
        assertEquals(http + "://" + host + target, RedirectServlet.toAbsoluteUri(http, host, portNone, target));
        assertEquals(https + "://" + host + target, RedirectServlet.toAbsoluteUri(https, host, portNone, target));
        assertEquals(scheme + "://" + host + target, RedirectServlet.toAbsoluteUri(scheme, host, portNone, target));
    }

    public void testGetStatus() {
        final int found = HttpServletResponse.SC_FOUND;
        final int valid = 768;
        final int invalidLow = 77;
        final int invalidHigh = 1234;
        final int min = 100;
        final int max = 999;

        assertStatus(found, -2);
        assertStatus(found, -1);
        assertStatus(found, invalidLow);
        assertStatus(found, invalidHigh);

        assertStatus(valid, valid);
        assertStatus(min, min);
        assertStatus(max, max);
    }

    public void testSameParent() {
        String base = "/a";
        String target = "/b";
        assertEqualsUri("/b", toRedirect(base, target), false);

        base = "/";
        target = "/a";
        assertEqualsUri("/a", toRedirect(base, target), false);

        base = "/a/b/c";
        target = "/a/b/d";
        assertEqualsUri("/a/b/d", toRedirect(base, target), false);
    }

    public void testTrailingSlash() {
        String base = "/a/b/c/";
        String target = "/a/b/c.html";
        assertEqualsUri("/a/b/c.html", toRedirect(base, target), false);
    }

    public void testCommonAncestor() {
        String base = "/a/b/c/d";
        String target = "/a/b/x/y";
        assertEqualsUri("/a/b/x/y", toRedirect(base, target), false);
    }

    public void testChild() {
        String base = "/a.html";
        String target = "/a/b.html";
        assertEqualsUri("/a/b.html", toRedirect(base, target), false);

        base = "/a";
        target = "/a/b.html";
        assertEqualsUri("/a/b.html", toRedirect(base, target), false);

        base = "/a";
        target = "/a/b";
        assertEqualsUri("/a/b", toRedirect(base, target), false);

        base = "/a.html";
        target = "/a/b/c.html";
        assertEqualsUri("/a/b/c.html", toRedirect(base, target), false);

        base = "/a";
        target = "/a/b/c.html";
        assertEqualsUri("/a/b/c.html", toRedirect(base, target), false);

        base = "/a";
        target = "/a/b/c";
        assertEqualsUri("/a/b/c", toRedirect(base, target), false);
    }

    public void testChildNonRoot() {
        String base = "/x/a.html";
        String target = "/x/a/b.html";
        assertEqualsUri("/x/a/b.html", toRedirect(base, target), false);

        base = "/x/a";
        target = "/x/a/b.html";
        assertEqualsUri("/x/a/b.html", toRedirect(base, target), false);

        base = "/x/a";
        target = "/x/a/b";
        assertEqualsUri("/x/a/b", toRedirect(base, target), false);

        base = "/x/a.html";
        target = "/x/a/b/c.html";
        assertEqualsUri("/x/a/b/c.html", toRedirect(base, target), false);

        base = "/x/a";
        target = "/x/a/b/c.html";
        assertEqualsUri("/x/a/b/c.html", toRedirect(base, target), false);

        base = "/x/a";
        target = "/x/a/b/c";
        assertEqualsUri("/x/a/b/c", toRedirect(base, target), false);
    }

    public void testChildRelative() {
        String base = "/a";
        String target = "b.html";
        assertEqualsUri("/a/b.html", toRedirect(base, target), false);

        base = "/a";
        target = "b";
        assertEqualsUri("/a/b", toRedirect(base, target), false);

        base = "/a";
        target = "b/c.html";
        assertEqualsUri("/a/b/c.html", toRedirect(base, target), false);

        base = "/a";
        target = "b/c";
        assertEqualsUri("/a/b/c", toRedirect(base, target), false);
    }

    public void testChildNonRootRelative() {
        String base = "/x/a";
        String target = "b.html";
        assertEqualsUri("/x/a/b.html", toRedirect(base, target), false);

        base = "/x/a";
        target = "b";
        assertEqualsUri("/x/a/b", toRedirect(base, target), false);

        base = "/x/a";
        target = "b/c.html";
        assertEqualsUri("/x/a/b/c.html", toRedirect(base, target), false);

        base = "/x/a";
        target = "b/c";
        assertEqualsUri("/x/a/b/c", toRedirect(base, target), false);
    }

    public void testUnCommon() {
        String base = "/a/b/c/d";
        String target = "/w/x/y/z";
        assertEqualsUri("/w/x/y/z", toRedirect(base, target), false);
    }

    public void testSibbling() {
        String base = "/a/b";
        String target0 = "../y/z";
        assertEqualsUri("/a/y/z", toRedirect(base, target0), false);

        String target1 = "../../y/z";
        assertEqualsUri("/y/z", toRedirect(base, target1), false);

        String target2 = "../../../y/z";
        assertEqualsUri(base + "/" + target2, toRedirect(base, target2), false);
    }

    public void testSelectorsEtc() {
        assertEquals(null, null, null, null);

        assertEquals(null, "html", null, null);

        assertEquals("print", "html", null, null);

        assertEquals("print.a4", "html", null, null);

        assertEquals(null, "html", "/suffix.pdf", null);

        assertEquals(null, "html", null, "xy=1");

        assertEquals(null, "html", "/suffix.pdf", "xy=1");

        assertEquals("print.a4", "html", "/suffix.pdf", "xy=1");
    }

    public void testEmptyPath() {
        MockSlingHttpServletRequest request = new MockSlingHttpServletRequest("/", null, null, null, null, "",
                TEST_SCHEME, TEST_HOST, TEST_PORT, "/webapp");
        request.setResourceResolver(new MockResourceResolver());
        String path = RedirectServlet.toRedirectPath("/index.html", request);
        assertEqualsUri("/webapp/index.html", path, false);

        request = new MockSlingHttpServletRequest("/", null, null, null, null, "/", TEST_SCHEME, TEST_HOST, TEST_PORT,
                "/webapp");
        request.setResourceResolver(new MockResourceResolver());
        path = RedirectServlet.toRedirectPath("/index.html", request);
        assertEqualsUri("/webapp/index.html", path, false);
    }

    // ---------- Helper

    private static void assertEquals(String selectors, String extension, String suffix, String queryString) {
        final String basePath = "/a/b/c";
        final String targetPath = "/a/b/d";
        String expected = "/a/b/d";

        if (selectors != null) {
            expected += "." + selectors;
        }
        if (extension != null) {
            expected += "." + extension;
        }
        if (suffix != null) {
            expected += suffix;
        }
        if (queryString != null) {
            expected += "?" + queryString;
        }

        String actual = toRedirect(basePath, selectors, extension, suffix, queryString, targetPath);

        assertEqualsUri(expected, actual, false);
    }

    private static void assertEqualsUri(String expected, String actual, boolean isAbsolute) {
        if (isAbsolute) {
            assertEquals(expected, actual);
        } else {
            assertEquals(expected, actual);
        }
    }

    private static void assertStatus(final int expectedStatus, final int testStatus) {
        final ValueMap valueMap;
        if (testStatus == -2) {
            valueMap = null;
        } else if (testStatus == -1) {
            valueMap = new ValueMapDecorator(new HashMap<String, Object>());
        } else {
            valueMap = new ValueMapDecorator(
                    Collections.singletonMap(RedirectServlet.STATUS_PROP, (Object) testStatus));
        }

        final int actualStatus = RedirectServlet.getStatus(valueMap);

        assertEquals(expectedStatus, actualStatus);
    }

    private static String toRedirect(String basePath, String targetPath) {
        return toRedirect(basePath, null, null, null, null, targetPath);
    }

    private static String toRedirect(String basePath, String selectors, String extension, String suffix,
            String queryString, String targetPath) {
        MockSlingHttpServletRequest request = new MockSlingHttpServletRequest(basePath, selectors, extension, suffix,
                queryString, basePath, TEST_SCHEME, TEST_HOST, TEST_PORT, "");
        request.setResourceResolver(new MockResourceResolver());
        return RedirectServlet.toRedirectPath(targetPath, request);
    }

}
