/*
 * Copyright (c) 2003, 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.
 */

/*
 * @test
 * @bug 4957393
 * @summary Test that DescriptorSupport.toXMLString() can be used to
 * reconstruct an equivalent DescriptorSupport
 * @author Eamonn McManus
 * @run clean DescriptorSupportXMLTest
 * @run build DescriptorSupportXMLTest
 * @run main DescriptorSupportXMLTest
 */

import java.util.Arrays;

import javax.management.RuntimeOperationsException;
import javax.management.modelmbean.DescriptorSupport;

public class DescriptorSupportXMLTest {
    public static void main(String[] args) throws Exception {
        System.out.println("Testing that DescriptorSupport.toXMLString() " +
                           "can be used to reconstruct an equivalent " +
                           "DescriptorSupport");
        int failed = 0;

        final Object[] testValues = {
            // Values that should be encodable.
            "",
            "ok",
            "null",
            "(open",
            "close)",
            "(parens)",
            "quote\"quote",
            "a description with several words",
            "magic&\"\\<> \r\t\n\f;&;magic",
            "&lt;descriptor&gt;&&&&lt;/descriptor&gt;",
            "&lt;descriptor&gt;&&&&lt;/blahblahblah&gt;",
            null,
            new Integer(10),
            Boolean.TRUE,
            new Float(1.0f),

            // Values that are not encodable: it is important that we throw
            // an exception during encoding rather than waiting until decode
            // time to discover the problem.  These classes are not encodable
            // because they don't have a (String) constructor.
            new Character('!'),
            new java.util.HashMap(),
        };

        for (int i = 0; i < testValues.length; i++) {
            final Object v = testValues[i];
            final String what =
                (v == null) ? "null" :
                (v.getClass().getName() + "{" + v + "}");

            final DescriptorSupport in =
                new DescriptorSupport(new String[] {"bloo"}, new Object[] {v});

            final String xml;
            try {
                xml = in.toXMLString();
            } catch (RuntimeOperationsException e) {
                final Throwable cause = e.getCause();
                if (cause instanceof IllegalArgumentException) {
                    System.out.println("OK: " + what + ": got a " +
                                       "RuntimeOperationsException wrapping " +
                                       "an IllegalArgumentException: " +
                                       cause.getMessage());
                } else {
                    final String causeString =
                        (cause == null) ? "null" : cause.getClass().getName();
                    System.out.println("FAILED: " + what + ": got a " +
                                       "RuntimeOperationException wrapping " +
                                       causeString);
                    failed++;
                }
                continue;
            }

            System.out.println("Encoded " + what + " as " + xml);

            final DescriptorSupport out;
            try {
                out = new DescriptorSupport(xml);
            } catch (Exception e) {
                System.out.println("FAILED: " + what + ": got an exception:");
                e.printStackTrace(System.out);
                failed++;
                continue;
            }

            final String[] names = out.getFieldNames();
            if (names.length != 1 || !"bloo".equals(names[0])) {
                System.out.println("FAILED: decoded names wrong: " +
                                   Arrays.asList(names));
                failed++;
                continue;
            }

            final Object[] values = out.getFieldValues(names);
            if (values.length != 1) {
                System.out.println("FAILED: wrong number of values: " +
                                   Arrays.asList(values));
                failed++;
                continue;
            }

            final Object outValue = values[0];

            if (v == null) {
                if (outValue == null)
                    System.out.println("OK: decoded null value");
                else {
                    System.out.println("FAILED: decoded null value as " +
                                       outValue.getClass().getName() + "{" +
                                       outValue + "}");
                    failed++;
                }
                continue;
            }

            if (outValue == null) {
                System.out.println("FAILED: decoded non-null value as null");
                failed++;
                continue;
            }

            if (v.getClass() != outValue.getClass()) {
                System.out.println("FAILED: decoded value has class " +
                                   outValue.getClass().getName() + "{" +
                                   outValue + "}");
                failed++;
                continue;
            }

            if (v.equals(outValue))
                System.out.println("OK: decoded value is equal to original");
            else {
                System.out.println("FAILED: decoded value is different: {" +
                                   outValue + "}");
                failed++;
            }
        }

        if (failed == 0)
            System.out.println("OK: all tests passed");
        else {
            System.out.println("TEST FAILED: fail count: " + failed);
            System.exit(1);
        }
    }
}
