/*
 * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import static jdk.testlibrary.Asserts.*;

/* @test
 * @summary Tests the different assertions in the Assert class
 */
public class AssertsTest {
    private static class Foo implements Comparable<Foo> {
        final int id;
        public Foo(int id) {
            this.id = id;
        }

        public int compareTo(Foo f) {
            return new Integer(id).compareTo(new Integer(f.id));
        }
    }

    public static void main(String[] args) throws Exception {
        testLessThan();
        testLessThanOrEqual();
        testEquals();
        testGreaterThanOrEqual();
        testGreaterThan();
        testNotEquals();
        testNull();
        testNotNull();
        testTrue();
        testFalse();
    }

    private static void testLessThan() throws Exception {
        expectPass(Assertion.LT, 1, 2);

        expectFail(Assertion.LT, 2, 2);
        expectFail(Assertion.LT, 2, 1);
        expectFail(Assertion.LT, null, 2);
        expectFail(Assertion.LT, 2, null);
    }

    private static void testLessThanOrEqual() throws Exception {
        expectPass(Assertion.LTE, 1, 2);
        expectPass(Assertion.LTE, 2, 2);

        expectFail(Assertion.LTE, 3, 2);
        expectFail(Assertion.LTE, null, 2);
        expectFail(Assertion.LTE, 2, null);
    }

    private static void testEquals() throws Exception {
        expectPass(Assertion.EQ, 1, 1);
        expectPass(Assertion.EQ, null, null);

        Foo f1 = new Foo(1);
        expectPass(Assertion.EQ, f1, f1);

        Foo f2 = new Foo(1);
        expectFail(Assertion.EQ, f1, f2);
        expectFail(Assertion.LTE, null, 2);
        expectFail(Assertion.LTE, 2, null);
    }

    private static void testGreaterThanOrEqual() throws Exception {
        expectPass(Assertion.GTE, 1, 1);
        expectPass(Assertion.GTE, 2, 1);

        expectFail(Assertion.GTE, 1, 2);
        expectFail(Assertion.GTE, null, 2);
        expectFail(Assertion.GTE, 2, null);
    }

    private static void testGreaterThan() throws Exception {
        expectPass(Assertion.GT, 2, 1);

        expectFail(Assertion.GT, 1, 1);
        expectFail(Assertion.GT, 1, 2);
        expectFail(Assertion.GT, null, 2);
        expectFail(Assertion.GT, 2, null);
    }

    private static void testNotEquals() throws Exception {
        expectPass(Assertion.NE, null, 1);
        expectPass(Assertion.NE, 1, null);

        Foo f1 = new Foo(1);
        Foo f2 = new Foo(1);
        expectPass(Assertion.NE, f1, f2);

        expectFail(Assertion.NE, null, null);
        expectFail(Assertion.NE, f1, f1);
        expectFail(Assertion.NE, 1, 1);
    }

    private static void testNull() throws Exception {
        expectPass(Assertion.NULL, null);

        expectFail(Assertion.NULL, 1);
    }

    private static void testNotNull() throws Exception {
        expectPass(Assertion.NOTNULL, 1);

        expectFail(Assertion.NOTNULL, null);
    }

    private static void testTrue() throws Exception {
        expectPass(Assertion.TRUE, true);

        expectFail(Assertion.TRUE, false);
    }

    private static void testFalse() throws Exception {
        expectPass(Assertion.FALSE, false);

        expectFail(Assertion.FALSE, true);
    }

    private static <T extends Comparable<T>> void expectPass(Assertion assertion, T ... args)
        throws Exception {
        Assertion.run(assertion, args);
    }

    private static <T extends Comparable<T>> void expectFail(Assertion assertion, T ... args)
        throws Exception {
        try {
            Assertion.run(assertion, args);
        } catch (RuntimeException e) {
            return;
        }
        throw new Exception("Expected " + Assertion.format(assertion, (Object[]) args) +
                            " to throw a RuntimeException");
    }

}

enum Assertion {
    LT, LTE, EQ, GTE, GT, NE, NULL, NOTNULL, FALSE, TRUE;

    public static <T extends Comparable<T>> void run(Assertion assertion, T ... args) {
        String msg = "Expected " + format(assertion, args) + " to pass";
        switch (assertion) {
            case LT:
                assertLessThan(args[0], args[1], msg);
                break;
            case LTE:
                assertLessThanOrEqual(args[0], args[1], msg);
                break;
            case EQ:
                assertEquals(args[0], args[1], msg);
                break;
            case GTE:
                assertGreaterThanOrEqual(args[0], args[1], msg);
                break;
            case GT:
                assertGreaterThan(args[0], args[1], msg);
                break;
            case NE:
                assertNotEquals(args[0], args[1], msg);
                break;
            case NULL:
                assertNull(args == null ? args : args[0], msg);
                break;
            case NOTNULL:
                assertNotNull(args == null ? args : args[0], msg);
                break;
            case FALSE:
                assertFalse((Boolean) args[0], msg);
                break;
            case TRUE:
                assertTrue((Boolean) args[0], msg);
                break;
            default:
                // do nothing
        }
    }

    public static String format(Assertion assertion, Object ... args) {
        switch (assertion) {
            case LT:
                return asString("assertLessThan", args);
            case LTE:
                return asString("assertLessThanOrEqual", args);
            case EQ:
                return asString("assertEquals", args);
            case GTE:
                return asString("assertGreaterThanOrEquals", args);
            case GT:
                return asString("assertGreaterThan", args);
            case NE:
                return asString("assertNotEquals", args);
            case NULL:
                return asString("assertNull", args);
            case NOTNULL:
                return asString("assertNotNull", args);
            case FALSE:
                return asString("assertFalse", args);
            case TRUE:
                return asString("assertTrue", args);
            default:
                return "";
        }
    }

    private static String asString(String assertion, Object ... args) {
        if (args == null) {
            return String.format("%s(null)", assertion);
        }
        if (args.length == 1) {
            return String.format("%s(%s)", assertion, args[0]);
        } else {
            return String.format("%s(%s, %s)", assertion, args[0], args[1]);
        }
    }
}
