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

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

public class TestCookieProcessorGeneration {

    @Test
    public void v0SimpleCookie() {
        doTest(new Cookie("foo", "bar"), "foo=bar");
    }

    @Test
    public void v0NullValue() {
        doTest(new Cookie("foo", null), "foo=\"\"", "foo=");
    }

    @Test
    public void v0QuotedValue() {
        doTest(new Cookie("foo", "\"bar\""), "foo=\"bar\"");
    }

    @Test
    public void v0ValueContainsSemicolon() {
        doTest(new Cookie("foo", "a;b"), "foo=\"a;b\"; Version=1", null);
    }

    @Test
    public void v0ValueContainsComma() {
        doTest(new Cookie("foo", "a,b"), "foo=\"a,b\"; Version=1", null);
    }

    @Test
    public void v0ValueContainsSpace() {
        doTest(new Cookie("foo", "a b"), "foo=\"a b\"; Version=1", null);
    }

    @Test
    public void v0ValueContainsEquals() {
        Cookie cookie = new Cookie("foo", "a=b");
        doTestDefaults(cookie, "foo=\"a=b\"; Version=1", "foo=a=b");
        doTestAllowSeparators(cookie, "foo=a=b", "foo=a=b");
    }

    @Test
    public void v0ValueContainsQuote() {
        Cookie cookie = new Cookie("foo", "a\"b");
        doTestDefaults(cookie,"foo=\"a\\\"b\"; Version=1", null);
        doTestAllowSeparators(cookie,"foo=a\"b", null);
    }

    @Test
    public void v0ValueContainsNonV0Separator() {
        Cookie cookie = new Cookie("foo", "a()<>@:\\\"/[]?={}b");
        doTestDefaults(cookie,"foo=\"a()<>@:\\\\\\\"/[]?={}b\"; Version=1", null);
        doTestAllowSeparators(cookie,"foo=a()<>@:\\\"/[]?={}b", null);
    }

    @Test
    public void v0ValueContainsBackslash() {
        Cookie cookie = new Cookie("foo", "a\\b");
        doTestDefaults(cookie, "foo=\"a\\\\b\"; Version=1", null);
        doTestAllowSeparators(cookie, "foo=a\\b", null);
    }

    @Test
    public void v0ValueContainsBackslashAtEnd() {
        Cookie cookie = new Cookie("foo", "a\\");
        doTestDefaults(cookie, "foo=\"a\\\\\"; Version=1", null);
        doTestAllowSeparators(cookie, "foo=a\\", null);
    }

    @Test
    public void v0ValueContainsBackslashAndQuote() {
        Cookie cookie = new Cookie("foo", "a\"b\\c");
        doTestDefaults(cookie, "foo=\"a\\\"b\\\\c\"; Version=1", null);
        doTestAllowSeparators(cookie, "foo=a\"b\\c", null);
    }

    @Test
    public void v1simpleCookie() {
        Cookie cookie = new Cookie("foo", "bar");
        cookie.setVersion(1);
        doTest(cookie, "foo=bar; Version=1", "foo=bar");
    }

    @Test
    public void v1NullValue() {
        Cookie cookie = new Cookie("foo", null);
        cookie.setVersion(1);
        doTest(cookie, "foo=\"\"; Version=1", "foo=");
    }

    @Test
    public void v1QuotedValue() {
        Cookie cookie = new Cookie("foo", "\"bar\"");
        cookie.setVersion(1);
        doTest(cookie, "foo=\"bar\"; Version=1", "foo=\"bar\"");
    }

    @Test
    public void v1ValueContainsSemicolon() {
        Cookie cookie = new Cookie("foo", "a;b");
        cookie.setVersion(1);
        doTest(cookie, "foo=\"a;b\"; Version=1", null);
    }

    @Test
    public void v1ValueContainsComma() {
        Cookie cookie = new Cookie("foo", "a,b");
        cookie.setVersion(1);
        doTest(cookie, "foo=\"a,b\"; Version=1", null);
    }

    @Test
    public void v1ValueContainsSpace() {
        Cookie cookie = new Cookie("foo", "a b");
        cookie.setVersion(1);
        doTest(cookie, "foo=\"a b\"; Version=1", null);
    }

    @Test
    public void v1ValueContainsEquals() {
        Cookie cookie = new Cookie("foo", "a=b");
        cookie.setVersion(1);
        doTest(cookie, "foo=\"a=b\"; Version=1", "foo=a=b");
    }

    @Test
    public void v1ValueContainsQuote() {
        Cookie cookie = new Cookie("foo", "a\"b");
        cookie.setVersion(1);
        doTest(cookie, "foo=\"a\\\"b\"; Version=1", null);
    }

    @Test
    public void v1ValueContainsNonV0Separator() {
        Cookie cookie = new Cookie("foo", "a()<>@,;:\\\"/[]?={}b");
        cookie.setVersion(1);
        doTest(cookie, "foo=\"a()<>@,;:\\\\\\\"/[]?={}b\"; Version=1", null);
    }

    @Test
    public void v1ValueContainsBackslash() {
        Cookie cookie = new Cookie("foo", "a\\b");
        cookie.setVersion(1);
        doTest(cookie, "foo=\"a\\\\b\"; Version=1", null);
    }

    @Test
    public void v1ValueContainsBackslashAndQuote() {
        Cookie cookie = new Cookie("foo", "a\"b\\c");
        cookie.setVersion(1);
        doTest(cookie, "foo=\"a\\\"b\\\\c\"; Version=1", null);
    }

    @Test
    public void v1ValueUTF8() {
        String value = "\u2300";
        Cookie cookie = new Cookie("foo", value);
        cookie.setVersion(1);
        doTest(cookie, (String) null, "foo=" + value);
    }

    @Test
    public void v1TestMaxAgePositive() {
        doV1TestMaxAge(100, "foo=bar; Version=1; Max-Age=100", "foo=bar; Max-Age=100");
    }

    @Test
    public void v1TestMaxAgeZero() {
        doV1TestMaxAge(0, "foo=bar; Version=1; Max-Age=0",
                "foo=bar; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT");
    }

    @Test
    public void v1TestMaxAgeNegative() {
        doV1TestMaxAge(-100, "foo=bar; Version=1", "foo=bar");
    }

    @Test
    public void v1TestDomainValid01() {
        doV1TestDomain("example.com", "foo=bar; Version=1; Domain=example.com",
                "foo=bar; Domain=example.com");
    }

    @Test
    public void v1TestDomainValid02() {
        doV1TestDomain("exa-mple.com", "foo=bar; Version=1; Domain=exa-mple.com",
                "foo=bar; Domain=exa-mple.com");
    }

    @Test
    public void v1TestDomainInvalid01() {
        doV1TestDomain("example.com.", "foo=bar; Version=1; Domain=example.com.", null);
    }

    @Test
    public void v1TestDomainInvalid02() {
        doV1TestDomain("example.com-", "foo=bar; Version=1; Domain=example.com-", null);
    }

    @Test
    public void v1TestDomainInvalid03() {
        doV1TestDomain(".example.com.", "foo=bar; Version=1; Domain=.example.com.", null);
    }

    @Test
    public void v1TestDomainInvalid04() {
        doV1TestDomain("-example.com.", "foo=bar; Version=1; Domain=-example.com.", null);
    }

    @Test
    public void v1TestDomainInvalid05() {
        doV1TestDomain("example..com.", "foo=bar; Version=1; Domain=example..com.", null);
    }

    @Test
    public void v1TestDomainInvalid06() {
        doV1TestDomain("example-.com.", "foo=bar; Version=1; Domain=example-.com.", null);
    }

    @Test
    public void v1TestDomainInvalid07() {
        doV1TestDomain("exam$ple.com.", "foo=bar; Version=1; Domain=exam$ple.com.", null);
    }

    @Test
    public void v1TestPathValid() {
        doV1TestPath("/example", "foo=bar; Version=1; Path=/example",
                "foo=bar; Path=/example");
    }

    @Test
    public void v1TestPathInvalid01() {
        doV1TestPath("exa\tmple", "foo=bar; Version=1; Path=\"exa\tmple\"", null);
    }


    private void doTest(Cookie cookie, String expected) {
        doTest(cookie, expected, expected);
    }


    private void doTest(Cookie cookie,
            String expectedLegacy, String expectedRfc6265) {
        doTestDefaults(cookie, expectedLegacy, expectedRfc6265);
        doTestAllowSeparators(cookie, expectedLegacy, expectedRfc6265);
    }


    private void doTestDefaults(Cookie cookie,
            String expectedLegacy, String expectedRfc6265) {
        CookieProcessor legacy = new LegacyCookieProcessor();
        CookieProcessor rfc6265 = new Rfc6265CookieProcessor();
        doTest(cookie, legacy, expectedLegacy, rfc6265, expectedRfc6265);
    }


    private void doTestAllowSeparators(Cookie cookie,
            String expectedLegacy, String expectedRfc6265) {
        LegacyCookieProcessor legacy = new LegacyCookieProcessor();
        legacy.setAllowHttpSepsInV0(true);
        legacy.setForwardSlashIsSeparator(true);
        CookieProcessor rfc6265 = new Rfc6265CookieProcessor();
        doTest(cookie, legacy, expectedLegacy, rfc6265, expectedRfc6265);
    }


    private void doTest(Cookie cookie,
            CookieProcessor legacy, String expectedLegacy,
            CookieProcessor rfc6265, String expectedRfc6265) {
        doTest(cookie, legacy, expectedLegacy);
        doTest(cookie, rfc6265, expectedRfc6265);
    }


    private void doTest(Cookie cookie, CookieProcessor cookieProcessor, String expected) {
        if (expected == null) {
            IllegalArgumentException e = null;
            try {
                cookieProcessor.generateHeader(cookie);
            } catch (IllegalArgumentException iae) {
                e = iae;
            }
            Assert.assertNotNull("Failed to throw IAE", e);
        } else {
            if (cookieProcessor instanceof Rfc6265CookieProcessor &&
                    cookie.getMaxAge() > 0) {
                // Expires attribute will depend on time cookie is generated so
                // use a modified test
                Assert.assertTrue(cookieProcessor.generateHeader(cookie).startsWith(expected));
            } else {
                Assert.assertEquals(expected, cookieProcessor.generateHeader(cookie));
            }
        }
    }


    private void doV1TestMaxAge(int age, String expectedLegacy, String expectedRfc6265) {
        LegacyCookieProcessor legacy = new LegacyCookieProcessor();
        legacy.setAlwaysAddExpires(false);
        Cookie cookie = new Cookie("foo", "bar");
        cookie.setVersion(1);
        cookie.setMaxAge(age);
        doTest(cookie, legacy, expectedLegacy, new Rfc6265CookieProcessor(), expectedRfc6265);
    }


    private void doV1TestDomain(String domain, String expectedLegacy, String expectedRfc6265) {
        LegacyCookieProcessor legacy = new LegacyCookieProcessor();
        legacy.setAlwaysAddExpires(false);
        Cookie cookie = new Cookie("foo", "bar");
        cookie.setVersion(1);
        cookie.setDomain(domain);
        doTest(cookie, legacy, expectedLegacy, new Rfc6265CookieProcessor(), expectedRfc6265);
    }


    private void doV1TestPath(String path, String expectedLegacy, String expectedRfc6265) {
        LegacyCookieProcessor legacy = new LegacyCookieProcessor();
        legacy.setAlwaysAddExpires(false);
        Cookie cookie = new Cookie("foo", "bar");
        cookie.setVersion(1);
        cookie.setPath(path);
        doTest(cookie, legacy, expectedLegacy, new Rfc6265CookieProcessor(), expectedRfc6265);
    }
}
