/*
 *  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.http;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Enumeration;

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

public class TestParameters {

    private static final Parameter SIMPLE =
        new Parameter("foo1", "bar1");
    private static final Parameter SIMPLE_MULTIPLE =
        new Parameter("foo2", "bar1", "bar2", "hello world", "?%@");
    private static final Parameter NO_VALUE =
        new Parameter("foo3");
    private static final Parameter EMPTY_VALUE =
        new Parameter("foo4", "");
    private static final Parameter EMPTY =
        new Parameter("");
    private static final Parameter UTF8 =
            new Parameter("\ufb6b\ufb6a\ufb72", "\uffee\uffeb\uffe2");

    @Test
    public void testProcessParametersByteArrayIntInt() {
        doTestProcessParametersByteArrayIntInt(-1, SIMPLE);
        doTestProcessParametersByteArrayIntInt(-1, SIMPLE_MULTIPLE);
        doTestProcessParametersByteArrayIntInt(-1, NO_VALUE);
        doTestProcessParametersByteArrayIntInt(-1, EMPTY_VALUE);
        doTestProcessParametersByteArrayIntInt(-1, EMPTY);
        doTestProcessParametersByteArrayIntInt(-1, UTF8);
        doTestProcessParametersByteArrayIntInt(-1,
                SIMPLE, SIMPLE_MULTIPLE, NO_VALUE, EMPTY_VALUE, EMPTY, UTF8);
        doTestProcessParametersByteArrayIntInt(-1,
                SIMPLE_MULTIPLE, NO_VALUE, EMPTY_VALUE, EMPTY, UTF8, SIMPLE);
        doTestProcessParametersByteArrayIntInt(-1,
                NO_VALUE, EMPTY_VALUE, EMPTY, UTF8, SIMPLE, SIMPLE_MULTIPLE);
        doTestProcessParametersByteArrayIntInt(-1,
                EMPTY_VALUE, EMPTY, UTF8, SIMPLE, SIMPLE_MULTIPLE, NO_VALUE);
        doTestProcessParametersByteArrayIntInt(-1,
                EMPTY, UTF8, SIMPLE, SIMPLE_MULTIPLE, NO_VALUE, EMPTY_VALUE);
        doTestProcessParametersByteArrayIntInt(-1,
                UTF8, SIMPLE, SIMPLE_MULTIPLE, NO_VALUE, EMPTY_VALUE, EMPTY);

        doTestProcessParametersByteArrayIntInt(1,
                SIMPLE, NO_VALUE, EMPTY_VALUE, UTF8);
        doTestProcessParametersByteArrayIntInt(2,
                SIMPLE, NO_VALUE, EMPTY_VALUE, UTF8);
        doTestProcessParametersByteArrayIntInt(3,
                SIMPLE, NO_VALUE, EMPTY_VALUE, UTF8);
        doTestProcessParametersByteArrayIntInt(4,
                SIMPLE, NO_VALUE, EMPTY_VALUE, UTF8);
    }

    // Make sure the inner Parameter class behaves correctly
    @Test
    public void testInternal() {
        Assert.assertEquals("foo1=bar1", SIMPLE.toString());
        // Note: testing requires that ' ' is encoded as '+',
        // because that is what browsers will send us.
        Assert.assertEquals("foo2=bar1&foo2=bar2&foo2=hello+world&foo2=%3F%25%40",
                SIMPLE_MULTIPLE.toString());
        Assert.assertEquals("foo3", NO_VALUE.toString());
        Assert.assertEquals("foo4=", EMPTY_VALUE.toString());
    }

    private long doTestProcessParametersByteArrayIntInt(int limit,
            Parameter... parameters) {

        // Build the byte array
        StringBuilder input = new StringBuilder();
        boolean first = true;
        for (Parameter parameter : parameters) {
            if (first) {
                first = false;
            } else {
                input.append('&');
            }
            input.append(parameter.toString());
        }

        byte[] data = input.toString().getBytes();

        Parameters p = new Parameters();
        p.setEncoding("UTF-8");
        p.setLimit(limit);

        long start = System.nanoTime();
        p.processParameters(data, 0, data.length);
        long end = System.nanoTime();

        if (limit == -1) {
            validateParameters(parameters, p);
        } else {
            Parameter[] limitParameters = new Parameter[limit];
            System.arraycopy(parameters, 0, limitParameters, 0, limit);
            validateParameters(limitParameters, p);
        }
        return end - start;
    }

    @Test
    public void testNonExistantParameter() {
        Parameters p = new Parameters();

        String value = p.getParameter("foo");
        Assert.assertNull(value);

        Enumeration<String> names = p.getParameterNames();
        Assert.assertFalse(names.hasMoreElements());

        String[] values = p.getParameterValues("foo");
        Assert.assertNull(values);
    }


    @Test
    public void testAddParameters() {
        Parameters p = new Parameters();

        // Empty at this point
        Enumeration<String> names = p.getParameterNames();
        Assert.assertFalse(names.hasMoreElements());
        String[] values = p.getParameterValues("foo");
        Assert.assertNull(values);

        // Add a parameter with two values
        p.addParameter("foo", "value1");
        p.addParameter("foo", "value2");

        names = p.getParameterNames();
        Assert.assertTrue(names.hasMoreElements());
        Assert.assertEquals("foo", names.nextElement());
        Assert.assertFalse(names.hasMoreElements());

        values = p.getParameterValues("foo");
        Assert.assertEquals(2, values.length);
        Assert.assertEquals("value1", values[0]);
        Assert.assertEquals("value2", values[1]);

        // Add two more values
        p.addParameter("foo", "value3");
        p.addParameter("foo", "value4");

        names = p.getParameterNames();
        Assert.assertTrue(names.hasMoreElements());
        Assert.assertEquals("foo", names.nextElement());
        Assert.assertFalse(names.hasMoreElements());

        values = p.getParameterValues("foo");
        Assert.assertEquals(4, values.length);
        Assert.assertEquals("value1", values[0]);
        Assert.assertEquals("value2", values[1]);
        Assert.assertEquals("value3", values[2]);
        Assert.assertEquals("value4", values[3]);
    }

    @Test
    public void testAddParametersLimit() {
        Parameters p = new Parameters();

        p.setLimit(2);

        // Empty at this point
        Enumeration<String> names = p.getParameterNames();
        Assert.assertFalse(names.hasMoreElements());
        String[] values = p.getParameterValues("foo1");
        Assert.assertNull(values);

        // Add a parameter
        p.addParameter("foo1", "value1");

        names = p.getParameterNames();
        Assert.assertTrue(names.hasMoreElements());
        Assert.assertEquals("foo1", names.nextElement());
        Assert.assertFalse(names.hasMoreElements());

        values = p.getParameterValues("foo1");
        Assert.assertEquals(1, values.length);
        Assert.assertEquals("value1", values[0]);

        // Add another parameter
        p.addParameter("foo2", "value2");

        names = p.getParameterNames();
        Assert.assertTrue(names.hasMoreElements());
        Assert.assertEquals("foo1", names.nextElement());
        Assert.assertEquals("foo2", names.nextElement());
        Assert.assertFalse(names.hasMoreElements());

        values = p.getParameterValues("foo1");
        Assert.assertEquals(1, values.length);
        Assert.assertEquals("value1", values[0]);

        values = p.getParameterValues("foo2");
        Assert.assertEquals(1, values.length);
        Assert.assertEquals("value2", values[0]);

        // Add another parameter
        IllegalStateException e = null;
        try {
            p.addParameter("foo3", "value3");
        } catch (IllegalStateException ise) {
            e = ise;
        }
        Assert.assertNotNull(e);

        // Check current parameters remain unaffected
        names = p.getParameterNames();
        Assert.assertTrue(names.hasMoreElements());
        Assert.assertEquals("foo1", names.nextElement());
        Assert.assertEquals("foo2", names.nextElement());
        Assert.assertFalse(names.hasMoreElements());

        values = p.getParameterValues("foo1");
        Assert.assertEquals(1, values.length);
        Assert.assertEquals("value1", values[0]);

        values = p.getParameterValues("foo2");
        Assert.assertEquals(1, values.length);
        Assert.assertEquals("value2", values[0]);

    }

    private void validateParameters(Parameter[] parameters, Parameters p) {
        Enumeration<String> names = p.getParameterNames();

        int i = 0;
        while (names.hasMoreElements()) {
            while (parameters[i].getName() == null) {
                i++;
            }

            String name = names.nextElement();
            String[] values = p.getParameterValues(name);

            boolean match = false;

            for (Parameter parameter : parameters) {
                if (name.equals(parameter.getName())) {
                    match = true;
                    if (parameter.values.length == 0) {
                        // Special case
                        Assert.assertArrayEquals(new String[] {""}, values);
                    } else {
                        Assert.assertArrayEquals(parameter.getValues(), values);
                    }
                    break;
                }
            }
            Assert.assertTrue(match);
        }
    }

    private static class Parameter {
        private final String name;
        private final String[] values;

        public Parameter(String name, String... values) {
            this.name = name;
            this.values = values;
        }

        public String getName() {
            return name;
        }

        public String[] getValues() {
            return values;
        }

        @Override
        public String toString() {
            try {
                StringBuilder result = new StringBuilder();
                boolean first = true;
                if (values.length == 0) {
                    return URLEncoder.encode(name, "UTF-8");
                }
                for (String value : values) {
                    if (first) {
                        first = false;
                    } else {
                        result.append('&');
                    }
                    if (name != null) {
                        result.append(URLEncoder.encode(name, "UTF-8"));
                    }
                    if (value != null) {
                        result.append('=');
                        result.append(URLEncoder.encode(value, "UTF-8"));
                    }
                }
                return result.toString();
            } catch (UnsupportedEncodingException ex) {
                return ex.toString();
            }
        }
    }
}
