/*
 * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/**
 * @test
 * @summary Unit test for java.net.HttpCookie
 * @bug 6244040 6277796 6277801 6277808 6294071
 * @author Edward Wang
 */

import java.net.HttpCookie;
import java.util.List;

public class TestHttpCookie {
    private static int testCount = 0;

    private String cHeader = null;
    private List<HttpCookie> cookies = null;

    // test case here expressed as a string, which represents
    // the header string to be parsed into HttpCookie instance.
    // A TestHttpCookie instance will be created to hold such a HttpCookie
    // object, and TestHttpCookie class has utility methods to check equality
    // between HttpCookie's real property and expected property.
    static TestHttpCookie test(String cookieHeader) {
        testCount++;
        return new TestHttpCookie(cookieHeader);
    }

    TestHttpCookie(String cHeader) {
        assert cHeader != null;
        this.cHeader = cHeader;

        try {
            List<HttpCookie> cookies = HttpCookie.parse(cHeader);
            this.cookies = cookies;
        } catch (IllegalArgumentException ignored) {
            cookies = null;
        }
    }

    // check name
    TestHttpCookie n(int index, String n) {
        HttpCookie cookie = cookies.get(index);
        if (cookie == null || !n.equalsIgnoreCase(cookie.getName())) {
            raiseError("name", cookie.getName(), n);
        }

        return this;
    }
    TestHttpCookie n(String n) { return n(0, n); }

    // check value
    TestHttpCookie v(int index, String v) {
        HttpCookie cookie = cookies.get(index);
        if (cookie == null || !v.equals(cookie.getValue())) {
            raiseError("value", cookie.getValue(), v);
        }

        return this;
    }
    TestHttpCookie v(String v) { return v(0, v); }

    // check version
    TestHttpCookie ver(int index, int ver) {
        HttpCookie cookie = cookies.get(index);
        if (cookie == null || (ver != cookie.getVersion())) {
            raiseError("version", Integer.toString(cookie.getVersion()), Integer.toString(ver));
        }

        return this;
    }
    TestHttpCookie ver(int ver) { return ver(0, ver); }

    // check path
    TestHttpCookie p(int index, String p) {
        HttpCookie cookie = cookies.get(index);
        if (cookie == null || !p.equals(cookie.getPath())) {
            raiseError("path", cookie.getPath(), p);
        }

        return this;
    }
    TestHttpCookie p(String p) { return p(0, p); }

    // check null-ability
    TestHttpCookie nil() {
        if (cookies != null) {
            raiseError("Check null-ability fail");
        }

        return this;
    }

    // check comment
    TestHttpCookie c(int index, String c) {
        HttpCookie cookie = cookies.get(index);
        if (cookie == null || !c.equals(cookie.getComment())) {
            raiseError("comment", cookie.getComment(), c);
        }

        return this;
    }
    TestHttpCookie c(String c) { return c(0, c); }

    // check comment url
    TestHttpCookie cu(int index, String cu) {
        HttpCookie cookie = cookies.get(index);
        if (cookie == null || !cu.equals(cookie.getCommentURL())) {
            raiseError("comment url", cookie.getCommentURL(), cu);
        }

        return this;
    }
    TestHttpCookie cu(String cu) { return cu(0, cu); }

    // check discard
    TestHttpCookie dsc(int index, boolean dsc) {
        HttpCookie cookie = cookies.get(index);
        if (cookie == null || (dsc != cookie.getDiscard())) {
            raiseError("discard", Boolean.toString(cookie.getDiscard()), Boolean.toString(dsc));
        }

        return this;
    }
    TestHttpCookie dsc(boolean dsc) { return dsc(0, dsc); }

    // check domain
    TestHttpCookie d(int index, String d) {
        HttpCookie cookie = cookies.get(index);
        if (cookie == null || !d.equalsIgnoreCase(cookie.getDomain())) {
            raiseError("domain", cookie.getDomain(), d);
        }

        return this;
    }
    TestHttpCookie d(String d) { return d(0, d); }

    // check max-age
    TestHttpCookie a(int index, long a) {
        HttpCookie cookie = cookies.get(index);
        if (cookie == null || (a != cookie.getMaxAge())) {
            raiseError("max-age", Long.toString(cookie.getMaxAge()), Long.toString(a));
        }

        return this;
    }
    TestHttpCookie a(long a) { return a(0, a); }

    // check port list
    TestHttpCookie port(int index, String p) {
        HttpCookie cookie = cookies.get(index);
        if (cookie == null || !p.equals(cookie.getPortlist())) {
            raiseError("portlist", cookie.getPortlist(), p);
        }

        return this;
    }
    TestHttpCookie port(String p) { return port(0, p); }

    // check equality
    static void eq(HttpCookie ck1, HttpCookie ck2, boolean same) {
        testCount++;
        if (ck1.equals(ck2) != same) {
            raiseError("Comparison inconsistent: " + ck1 + " " + ck2
                    + " should " + (same ? "equal" : "not equal"));
        }

        int h1 = ck1.hashCode();
        int h2 = ck2.hashCode();
        if ((h1 == h2) != same) {
            raiseError("Comparison inconsistent: hashCode for " + ck1 + " " + ck2
                    + " should " + (same ? "equal" : "not equal"));
        }
    }

    // check domainMatches()
    static void dm(String domain, String host, boolean matches) {
        testCount++;
        if (HttpCookie.domainMatches(domain, host) != matches) {
            raiseError("Host " + host + (matches?" should ":" should not ") +
                        "domain-match with domain " + domain);
        }
    }

    void raiseError(String attr, String realValue, String expectedValue) {
        StringBuilder sb = new StringBuilder();
        sb.append("Cookie ").append(attr).append(" is ").append(realValue).
                append(", should be ").append(expectedValue).
                append(" (").append(cHeader).append(")");
        throw new RuntimeException(sb.toString());
    }

    static void raiseError(String prompt) {
        throw new RuntimeException(prompt);
    }

    static void runTests() {
        rfc2965();
        netscape();
        misc();
    }

    static void rfc2965() {
        header("Test using rfc 2965 syntax");

        test("set-cookie2: Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\"")
        .n("Customer").v("WILE_E_COYOTE").ver(1).p("/acme");

        // whitespace between attr and = sign
        test("set-cookie2: Customer = \"WILE_E_COYOTE\"; Version = \"1\"; Path = \"/acme\"")
        .n("Customer").v("WILE_E_COYOTE").ver(1).p("/acme");

        // $NAME is reserved; result should be null
        test("set-cookie2: $Customer = \"WILE_E_COYOTE\"; Version = \"1\"; Path = \"/acme\"")
        .nil();

        // a 'full' cookie
        test("set-cookie2: Customer=\"WILE_E_COYOTE\"" +
                ";Version=\"1\"" +
                ";Path=\"/acme\"" +
                ";Comment=\"this is a coyote\"" +
                ";CommentURL=\"http://www.coyote.org\"" +
                ";Discard" +
                ";Domain=\".coyote.org\"" +
                ";Max-Age=\"3600\"" +
                ";Port=\"80\"" +
                ";Secure")
        .n("Customer").v("WILE_E_COYOTE").ver(1).p("/acme")
        .c("this is a coyote").cu("http://www.coyote.org").dsc(true)
        .d(".coyote.org").a(3600).port("80");

        // a 'full' cookie, without leading set-cookie2 token
        test("Customer=\"WILE_E_COYOTE\"" +
                ";Version=\"1\"" +
                ";Path=\"/acme\"" +
                ";Comment=\"this is a coyote\"" +
                ";CommentURL=\"http://www.coyote.org\"" +
                ";Discard" +
                ";Domain=\".coyote.org\"" +
                ";Max-Age=\"3600\"" +
                ";Port=\"80\"" +
                ";Secure")
        .n("Customer").v("WILE_E_COYOTE").ver(1).p("/acme")
        .c("this is a coyote").cu("http://www.coyote.org").dsc(true)
        .d(".coyote.org").a(3600).port("80");

        // illegal characters in set-cookie header
        test("Set-Cookie2:Customer=;Version#=\"1\";Path=&\"/acme\"")
        .nil();

        // empty set-cookie string
        test("").nil();

        // NullPointerException expected
        try {
            test(null);
        } catch (NullPointerException ignored) {
            // no-op
        }

        // bug 6277796
        test("Set-Cookie2:Customer=\"dtftest\"; Discard; Secure; Domain=\".sun.com\"; Max-Age=\"100\"; Version=\"1\";  path=\"/www\"; Port=\"80\"")
        .n("Customer").v("dtftest").ver(1).d(".sun.com").p("/www").port("80").dsc(true).a(100);

        // bug 6277801
        test("Set-Cookie2:Customer=\"dtftest\"; Discard; Secure; Domain=\".sun.com\"; Max-Age=\"100\"; Version=\"1\";  path=\"/www\"; Port=\"80\"" +
                ";Domain=\".java.sun.com\"; Max-Age=\"200\"; path=\"/javadoc\"; Port=\"8080\"")
        .n("Customer").v("dtftest").ver(1).d(".sun.com").p("/www").port("80").dsc(true).a(100);

        // bug 6294071
        test("Set-Cookie2:Customer=\"dtftest\";Discard; Secure; Domain=\"sun.com\"; Max-Age=\"100\";Version=\"1\";  Path=\"/www\"; Port=\"80,8080\"")
        .n("Customer").v("dtftest").ver(1).d("sun.com").p("/www").port("80,8080").dsc(true).a(100);
        test("Set-Cookie2:Customer=\"developer\";Domain=\"sun.com\";Max-Age=\"100\";Path=\"/www\";Port=\"80,8080\";CommentURL=\"http://www.sun.com/java1,000,000.html\"")
        .n("Customer").v("developer").d("sun.com").p("/www").port("80,8080").a(100).cu("http://www.sun.com/java1,000,000.html");

        // a header string contains 2 cookies
        test("Set-Cookie2:C1=\"V1\";Domain=\".sun1.com\";path=\"/www1\";Max-Age=\"100\",C2=\"V2\";Domain=\".sun2.com\";path=\"/www2\";Max-Age=\"200\"")
        .n(0, "C1").v(0, "V1").p(0, "/www1").a(0, 100).d(0, ".sun1.com")
        .n(1, "C2").v(1, "V2").p(1, "/www2").a(1, 200).d(1, ".sun2.com");
    }

    static void netscape() {
        header("Test using netscape cookie syntax");

        test("set-cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT")
        .n("CUSTOMER").v("WILE_E_COYOTE").p("/").ver(0);

        // a Netscape cookie, without set-cookie leading token
        test("CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT")
        .n("CUSTOMER").v("WILE_E_COYOTE").p("/").ver(0);

        // a 'google' cookie
        test("Set-Cookie: PREF=ID=1eda537de48ac25d:CR=1:TM=1112868587:LM=1112868587:S=t3FPA-mT9lTR3bxU;" +
             "expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com")
        .n("PREF").v("ID=1eda537de48ac25d:CR=1:TM=1112868587:LM=1112868587:S=t3FPA-mT9lTR3bxU")
        .p("/").d(".google.com").ver(0);

        // bug 6277796
        test("set-cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT; Secure")
        .n("CUSTOMER").v("WILE_E_COYOTE").p("/").ver(0);

        // bug 6277801
        test("set-cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT; path=\"/acme\"")
        .n("CUSTOMER").v("WILE_E_COYOTE").p("/").ver(0);
    }

    static void misc() {
        header("Test equals()");

        // test equals()
        HttpCookie c1 = new HttpCookie("Customer", "WILE_E_COYOTE");
        c1.setDomain(".coyote.org");
        c1.setPath("/acme");
        HttpCookie c2 = (HttpCookie)c1.clone();
        eq(c1, c2, true);

        // test equals() when domain and path are null
        c1 = new HttpCookie("Customer", "WILE_E_COYOTE");
        c2 = new HttpCookie("CUSTOMER", "WILE_E_COYOTE");
        eq(c1, c2, true);

        // path is case-sensitive
        c1 = new HttpCookie("Customer", "WILE_E_COYOTE");
        c2 = new HttpCookie("CUSTOMER", "WILE_E_COYOTE");
        c1.setPath("/acme");
        c2.setPath("/ACME");
        eq(c1, c2, false);

        header("Test domainMatches()");
        dm(".foo.com",  "y.x.foo.com",      false);
        dm(".foo.com",  "x.foo.com",        true);
        dm(".com",      "whatever.com",     false);
        dm(".com.",     "whatever.com",     false);
        dm(".ajax.com", "ajax.com",         true);
        dm(".local",    "example.local",    true);

        // bug 6277808
        testCount++;
        try {
            c1 = new HttpCookie("", "whatever");
        } catch (IllegalArgumentException ignored) {
            // expected exception; no-op
        }
    }

    static void header(String prompt) {
        System.out.println("== " + prompt + " ==");
    }

    public static void main(String[] args) {
        runTests();

        System.out.println("Succeeded in running " + testCount + " tests.");
    }
}
