/*
 *  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.tomcat.util.descriptor.web;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Test case for {@link WebXml} fragment ordering.
 */
public class TestWebXmlOrdering {
    private WebXml app;
    private WebXml a;
    private WebXml b;
    private WebXml c;
    private WebXml d;
    private WebXml e;
    private WebXml f;
    private Map<String,WebXml> fragments;
    private int posA;
    private int posB;
    private int posC;
    private int posD;
    private int posE;
    private int posF;

    @Before
    public void setUp() {
        app = new WebXml();
        a = new WebXml();
        a.setName("a");
        b = new WebXml();
        b.setName("b");
        c = new WebXml();
        c.setName("c");
        d = new WebXml();
        d.setName("d");
        e = new WebXml();
        e.setName("e");
        f = new WebXml();
        f.setName("f");
        // Control the input order
        fragments = new LinkedHashMap<>();
        fragments.put("a",a);
        fragments.put("b",b);
        fragments.put("c",c);
        fragments.put("d",d);
        fragments.put("e",e);
        fragments.put("f",f);
    }

    @Test
    public void testOrderWebFragmentsAbsolute() {
        app.addAbsoluteOrdering("c");
        app.addAbsoluteOrdering("a");
        app.addAbsoluteOrdering("b");
        app.addAbsoluteOrdering("e");
        app.addAbsoluteOrdering("d");

        Set<WebXml> ordered = WebXml.orderWebFragments(app, fragments, null);

        Iterator<WebXml> iter = ordered.iterator();
        Assert.assertEquals(c,iter.next());
        Assert.assertEquals(a,iter.next());
        Assert.assertEquals(b,iter.next());
        Assert.assertEquals(e,iter.next());
        Assert.assertEquals(d,iter.next());
        Assert.assertFalse(iter.hasNext());
    }

    @Test
    public void testOrderWebFragmentsAbsolutePartial() {
        app.addAbsoluteOrdering("c");
        app.addAbsoluteOrdering("a");

        Set<WebXml> ordered = WebXml.orderWebFragments(app, fragments, null);

        Iterator<WebXml> iter = ordered.iterator();
        Assert.assertEquals(c,iter.next());
        Assert.assertEquals(a,iter.next());
        Assert.assertFalse(iter.hasNext());
    }

    @Test
    public void testOrderWebFragmentsAbsoluteOthersStart() {
        app.addAbsoluteOrdering(WebXml.ORDER_OTHERS);
        app.addAbsoluteOrdering("b");
        app.addAbsoluteOrdering("d");

        Set<WebXml> others = new HashSet<>();
        others.add(a);
        others.add(c);
        others.add(e);
        others.add(f);

        Set<WebXml> ordered = WebXml.orderWebFragments(app, fragments, null);

        Iterator<WebXml> iter = ordered.iterator();
        while (others.size() > 0) {
            WebXml o = iter.next();
            Assert.assertTrue(others.contains(o));
            others.remove(o);
        }
        Assert.assertEquals(b,iter.next());
        Assert.assertEquals(d,iter.next());
        Assert.assertFalse(iter.hasNext());
    }

    @Test
    public void testOrderWebFragmentsAbsoluteOthersMiddle() {
        app.addAbsoluteOrdering("b");
        app.addAbsoluteOrdering(WebXml.ORDER_OTHERS);
        app.addAbsoluteOrdering("d");

        Set<WebXml> others = new HashSet<>();
        others.add(a);
        others.add(c);
        others.add(e);
        others.add(f);

        Set<WebXml> ordered = WebXml.orderWebFragments(app, fragments, null);

        Iterator<WebXml> iter = ordered.iterator();
        Assert.assertEquals(b,iter.next());

        while (others.size() > 0) {
            WebXml o = iter.next();
            Assert.assertTrue(others.contains(o));
            others.remove(o);
        }
        Assert.assertEquals(d,iter.next());
        Assert.assertFalse(iter.hasNext());
    }

    @Test
    public void testWebFragmentsAbsoluteWrongFragmentName() {
        app.addAbsoluteOrdering("a");
        app.addAbsoluteOrdering("z");
        Set<WebXml> ordered = WebXml.orderWebFragments(app, fragments, null);
        Assert.assertEquals(1,ordered.size());
        Assert.assertEquals(fragments.get("a"),ordered.toArray()[0]);
    }

    @Test
    public void testOrderWebFragmentsAbsoluteOthersEnd() {
        app.addAbsoluteOrdering("b");
        app.addAbsoluteOrdering("d");
        app.addAbsoluteOrdering(WebXml.ORDER_OTHERS);

        Set<WebXml> others = new HashSet<>();
        others.add(a);
        others.add(c);
        others.add(e);
        others.add(f);

        Set<WebXml> ordered = WebXml.orderWebFragments(app, fragments, null);

        Iterator<WebXml> iter = ordered.iterator();
        Assert.assertEquals(b,iter.next());
        Assert.assertEquals(d,iter.next());

        while (others.size() > 0) {
            WebXml o = iter.next();
            Assert.assertTrue(others.contains(o));
            others.remove(o);
        }
        Assert.assertFalse(iter.hasNext());
    }

    private void doRelativeOrderingTest(RelativeOrderingTestRunner runner) {
        // Confirm we have all 720 possible input orders
        // Set<String> orders = new HashSet<>();

        // Test all possible input orders since some bugs were discovered that
        // depended on input order
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 5; j++) {
                for (int k = 0; k < 4; k++) {
                    for (int l = 0; l < 3; l++) {
                        for (int m = 0; m < 2; m++) {
                            setUp();
                            runner.init();
                            ArrayList<WebXml> source = new ArrayList<>();
                            source.addAll(fragments.values());
                            Map<String,WebXml> input =
                                    new LinkedHashMap<>();

                            WebXml one = source.remove(i);
                            input.put(one.getName(), one);

                            WebXml two = source.remove(j);
                            input.put(two.getName(), two);

                            WebXml three = source.remove(k);
                            input.put(three.getName(), three);

                            WebXml four = source.remove(l);
                            input.put(four.getName(), four);

                            WebXml five = source.remove(m);
                            input.put(five.getName(), five);

                            WebXml six = source.remove(0);
                            input.put(six.getName(), six);

                            /*
                            String order = one.getName() + two.getName() +
                                    three.getName() + four.getName() +
                                    five.getName() + six.getName();
                            orders.add(order);
                            */

                            Set<WebXml> ordered =
                                    WebXml.orderWebFragments(app, input, null);
                            populatePositions(ordered);

                            runner.validate(getOrder(ordered));
                        }
                    }
                }
            }
        }
        // System.out.println(orders.size());
    }

    private String getOrder(Set<WebXml> ordered) {
        StringBuilder sb = new StringBuilder(ordered.size());
        for (WebXml webXml : ordered) {
            sb.append(webXml.getName());
        }
        return sb.toString();
    }

    private void populatePositions(Set<WebXml> ordered) {
        List<WebXml> indexed = new ArrayList<>();
        indexed.addAll(ordered);

        posA = indexed.indexOf(a);
        posB = indexed.indexOf(b);
        posC = indexed.indexOf(c);
        posD = indexed.indexOf(d);
        posE = indexed.indexOf(e);
        posF = indexed.indexOf(f);
    }

    @Test
    public void testOrderWebFragmentsRelative1() {
        // First example from servlet spec
        doRelativeOrderingTest(new RelativeTestRunner1());
    }

    @Test
    public void testOrderWebFragmentsRelative2() {
        // Second example - use fragment a for no-id fragment
        doRelativeOrderingTest(new RelativeTestRunner2());
    }

    @Test
    public void testOrderWebFragmentsRelative3() {
        // Third example from spec with e & f added
        doRelativeOrderingTest(new RelativeTestRunner3());
    }

    @Test
    public void testOrderWebFragmentsRelative4Bug54068() {
        // Simple sequence that failed for some inputs
        doRelativeOrderingTest(new RelativeTestRunner4());
    }

    @Test
    public void testOrderWebFragmentsRelative5Bug54068() {
        // Simple sequence that failed for some inputs
        doRelativeOrderingTest(new RelativeTestRunner5());
    }

    @Test
    public void testOrderWebFragmentsRelative6Bug54068() {
        // Simple sequence that failed for some inputs
        doRelativeOrderingTest(new RelativeTestRunner6());
    }

    @Test
    public void testOrderWebFragmentsRelative7() {
        // Reference loop (but not circular dependencies)
        doRelativeOrderingTest(new RelativeTestRunner7());
    }

    @Test
    public void testOrderWebFragmentsRelative8() {
        // More complex, trying to break the algorithm
        doRelativeOrderingTest(new RelativeTestRunner8());
    }

    @Test
    public void testOrderWebFragmentsRelative9() {
        // Variation on bug 54068
        doRelativeOrderingTest(new RelativeTestRunner9());
    }

    @Test
    public void testOrderWebFragmentsRelative10() {
        // Variation on bug 54068
        doRelativeOrderingTest(new RelativeTestRunner10());
    }

    @Test
    public void testOrderWebFragmentsRelative11() {
        // Test references to non-existant fragments
        doRelativeOrderingTest(new RelativeTestRunner11());
    }

    @Test(expected=IllegalArgumentException.class)
    public void testOrderWebFragmentsrelativeCircular1() {
        a.addBeforeOrdering("b");
        b.addBeforeOrdering("a");

        WebXml.orderWebFragments(app, fragments, null);
    }

    @Test(expected=IllegalArgumentException.class)
    public void testOrderWebFragmentsrelativeCircular2() {
        a.addBeforeOrderingOthers();
        b.addAfterOrderingOthers();
        c.addBeforeOrdering("a");
        c.addAfterOrdering("b");

        WebXml.orderWebFragments(app, fragments, null);
    }

    private interface RelativeOrderingTestRunner {
        void init();
        void validate(String order);
    }

    private class RelativeTestRunner1 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            a.addAfterOrderingOthers();
            a.addAfterOrdering("c");
            b.addBeforeOrderingOthers();
            c.addAfterOrderingOthers();
            f.addBeforeOrderingOthers();
            f.addBeforeOrdering("b");
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            //a.addAfterOrderingOthers();
            Assert.assertTrue(order, posA > posB);
            Assert.assertTrue(order, posA > posC);
            Assert.assertTrue(order, posA > posD);
            Assert.assertTrue(order, posA > posE);
            Assert.assertTrue(order, posA > posF);

            // a.addAfterOrdering("c");
            Assert.assertTrue(order, posA > posC);

            // b.addBeforeOrderingOthers();
            Assert.assertTrue(order, posB < posC);

            // c.addAfterOrderingOthers();
            Assert.assertTrue(order, posC > posB);
            Assert.assertTrue(order, posC > posD);
            Assert.assertTrue(order, posC > posE);
            Assert.assertTrue(order, posC > posF);

            // f.addBeforeOrderingOthers();
            Assert.assertTrue(order, posF < posA);
            Assert.assertTrue(order, posF < posB);
            Assert.assertTrue(order, posF < posC);
            Assert.assertTrue(order, posF < posD);
            Assert.assertTrue(order, posF < posE);

            // f.addBeforeOrdering("b");
            Assert.assertTrue(order, posF < posB);
        }
    }

    private class RelativeTestRunner2 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            a.addAfterOrderingOthers();
            a.addBeforeOrdering("c");
            b.addBeforeOrderingOthers();
            d.addAfterOrderingOthers();
            e.addBeforeOrderingOthers();
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            // a.addAfterOrderingOthers();
            Assert.assertTrue(order, posA > posB);
            Assert.assertTrue(order, posA > posE);
            Assert.assertTrue(order, posA > posF);

            // a.addBeforeOrdering("c");
            Assert.assertTrue(order, posC > posA);
            Assert.assertTrue(order, posC > posB);
            Assert.assertTrue(order, posC > posE);
            Assert.assertTrue(order, posC > posF);

            // b.addBeforeOrderingOthers();
            Assert.assertTrue(order, posB < posA);
            Assert.assertTrue(order, posB < posC);
            Assert.assertTrue(order, posB < posD);
            Assert.assertTrue(order, posB < posF);

            // d.addAfterOrderingOthers();
            Assert.assertTrue(order, posD > posB);
            Assert.assertTrue(order, posD > posE);
            Assert.assertTrue(order, posD > posF);

            // e.addBeforeOrderingOthers();
            Assert.assertTrue(order, posE < posA);
            Assert.assertTrue(order, posE < posC);
            Assert.assertTrue(order, posE < posD);
            Assert.assertTrue(order, posE < posF);
        }
    }

    private class RelativeTestRunner3 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            a.addAfterOrdering("b");
            c.addBeforeOrderingOthers();
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            // a.addAfterOrdering("b");
            Assert.assertTrue(order, posA > posB);

            // c.addBeforeOrderingOthers();
            Assert.assertTrue(order, posC < posA);
            Assert.assertTrue(order, posC < posB);
            Assert.assertTrue(order, posC < posD);
            Assert.assertTrue(order, posC < posE);
            Assert.assertTrue(order, posC < posF);
        }
    }

    private class RelativeTestRunner4 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            b.addAfterOrdering("a");
            c.addAfterOrdering("b");
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            // b.addAfterOrdering("a");
            Assert.assertTrue(order, posB > posA);

            // c.addAfterOrdering("b");
            Assert.assertTrue(order, posC > posB);
        }
    }

    private class RelativeTestRunner5 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            b.addBeforeOrdering("a");
            c.addBeforeOrdering("b");
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            // b.addBeforeOrdering("a");
            Assert.assertTrue(order, posB < posA);

            // c.addBeforeOrdering("b");
            Assert.assertTrue(order, posC < posB);
        }
    }

    private class RelativeTestRunner6 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            b.addBeforeOrdering("a");
            b.addAfterOrdering("c");
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            // b.addBeforeOrdering("a");
            Assert.assertTrue(order, posB < posA);

            //b.addAfterOrdering("c");
            Assert.assertTrue(order, posB > posC);
        }
    }

    private class RelativeTestRunner7 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            b.addBeforeOrdering("a");
            c.addBeforeOrdering("b");
            a.addAfterOrdering("c");
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            // b.addBeforeOrdering("a");
            Assert.assertTrue(order, posB < posA);

            // c.addBeforeOrdering("b");
            Assert.assertTrue(order, posC < posB);

            // a.addAfterOrdering("c");
            Assert.assertTrue(order, posA > posC);
        }
    }

    private class RelativeTestRunner8 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            a.addBeforeOrderingOthers();
            a.addBeforeOrdering("b");
            b.addBeforeOrderingOthers();
            c.addAfterOrdering("b");
            d.addAfterOrdering("c");
            e.addAfterOrderingOthers();
            f.addAfterOrderingOthers();
            f.addAfterOrdering("e");
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            // a.addBeforeOrderingOthers();
            Assert.assertTrue(order, posA < posB);
            Assert.assertTrue(order, posA < posC);
            Assert.assertTrue(order, posA < posD);
            Assert.assertTrue(order, posA < posE);
            Assert.assertTrue(order, posA < posF);

            // a.addBeforeOrdering("b");
            Assert.assertTrue(order, posA < posB);

            // b.addBeforeOrderingOthers();
            Assert.assertTrue(order, posB < posC);
            Assert.assertTrue(order, posB < posD);
            Assert.assertTrue(order, posB < posE);
            Assert.assertTrue(order, posB < posF);

            // c.addAfterOrdering("b");
            Assert.assertTrue(order, posC > posB);

            // d.addAfterOrdering("c");
            Assert.assertTrue(order, posD > posC);

            // e.addAfterOrderingOthers();
            Assert.assertTrue(order, posE > posA);
            Assert.assertTrue(order, posE > posB);
            Assert.assertTrue(order, posE > posC);
            Assert.assertTrue(order, posE > posD);

            // f.addAfterOrderingOthers();
            Assert.assertTrue(order, posF > posA);
            Assert.assertTrue(order, posF > posB);
            Assert.assertTrue(order, posF > posC);
            Assert.assertTrue(order, posF > posD);
            Assert.assertTrue(order, posF > posE);

            // f.addAfterOrdering("e");
            Assert.assertTrue(order, posF > posE);
        }
    }

    private class RelativeTestRunner9 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            a.addBeforeOrderingOthers();
            b.addBeforeOrdering("a");
            c.addBeforeOrdering("b");
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            // a.addBeforeOrderingOthers();
            Assert.assertTrue(order, posA < posD);
            Assert.assertTrue(order, posA < posE);
            Assert.assertTrue(order, posA < posF);

            // b.addBeforeOrdering("a");
            Assert.assertTrue(order, posB < posA);

            // c.addBeforeOrdering("b");
            Assert.assertTrue(order, posC < posB);
        }
    }

    private class RelativeTestRunner10 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            a.addAfterOrderingOthers();
            b.addAfterOrdering("a");
            c.addAfterOrdering("b");
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            // a.addAfterOrderingOthers();
            Assert.assertTrue(order, posA > posD);
            Assert.assertTrue(order, posA > posE);
            Assert.assertTrue(order, posA > posF);

            // b.addAfterOrdering("a");
            Assert.assertTrue(order, posB > posA);

            // c.addAfterOrdering("b");
            Assert.assertTrue(order, posC > posB);
        }
    }

    private class RelativeTestRunner11 implements RelativeOrderingTestRunner {

        @Override
        public void init() {
            a.addAfterOrdering("b");
            b.addAfterOrdering("z");
            b.addBeforeOrdering("y");
        }

        @Override
        public void validate(String order) {
            // There is some duplication in the tests below - it is easier to
            // check the tests are complete this way.

            // a.addAfterOrdering("b");
            Assert.assertTrue(order, posA > posB);
        }
    }
}
