/*
 * Copyright (c) 2004, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

import com.sun.ejte.ccl.reporter.SimpleReporterAdapter;
import java.util.Random;
import javax.management.Attribute;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

/* Quicklooks the administrative dotted names.
 */
public class DottedNamesTest implements RemoteAdminQuicklookTest {

    private MBeanServerConnection mbsc;
    
    private static final String DNONS = "com.sun.appserv:name=dotted-name-get-set,type=dotted-name-support";
    private static final String ADMIN_LOG_SERVICE_DN = "server.log-service.module-log-levels.admin";
    private static final String ADMIN_LISTENER_NAME = "admin-listener"; //this is the default name
    private static final String HTTP_LISTENER_LIST_DN = "server.http-service.http-listener";
    private long start, end;
    public DottedNamesTest() {
    }
    public String test() {
        String status = null;
        try {
            start = System.currentTimeMillis();
            testLogLevelDottedName();
            testListHTTPListeners();
            status = SimpleReporterAdapter.PASS;
        } catch(final Exception e) {
            status = SimpleReporterAdapter.FAIL;
            throw new RuntimeException(e);
        }
        finally {
            end = System.currentTimeMillis();
        }
        return ( status ) ;
    }

    public void setMBeanServerConnection(MBeanServerConnection c) {
        this.mbsc = c;
    }

    public String getName() {
        final String name = this.getClass().getName() + ": Testing admin dotted names";
        return (name);
    }
    
    private void testLogLevelDottedName() throws RuntimeException {
        TestLogLevel set = selectLogLevel();
        System.out.println("Selected value randomly to set: " + set.name());
        TestLogLevel get = null;
        try {
            setLogLevel(set);
            get = getLogLevel();
            System.out.println("Received value from backend: " + set.name());
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
        if (!set.equals(get)) {
            throw new RuntimeException("The values don't match: " + "set: " + set + ", got: " + get);
        }
    }
    private TestLogLevel selectLogLevel() {
        final int h = TestLogLevel.values().length - 1;
        final Random r = new Random();
        final int index = r.nextInt(h);
        return ( TestLogLevel.values()[index] );
    }
    private void setLogLevel(final TestLogLevel level) throws Exception {
        final ObjectName on         = new ObjectName(DNONS);
        final String op             = "dottedNameSet";
        final String[] sign         = new String[]{"java.lang.String"};
        final String nv             = ADMIN_LOG_SERVICE_DN + "=" + level.name();
        final Object[] params       = new String[]{nv};
        mbsc.invoke(on, op, params, sign);
    }
    private TestLogLevel getLogLevel() throws Exception {
        final ObjectName on         = new ObjectName(DNONS);
        final String op             = "dottedNameGet";
        final String[] sign         = new String[]{"java.lang.String"};
        final Object[] params       = new String[]{ADMIN_LOG_SERVICE_DN};
        final String value          = (String)((Attribute)mbsc.invoke(on, op, params, sign)).getValue();
        return ( TestLogLevel.valueOf(value) );
    }
    private void testListHTTPListeners() throws Exception {
        final String[] dns          = getListeners();
        boolean exists              = false;
        for (String s : dns) {
            System.out.println("Listener name = " + s);
            if (s.endsWith(ADMIN_LISTENER_NAME)) {
                exists = true;
                //break;
            }
        }
        if (!exists) 
            throw new RuntimeException("The admin listener does not exist, this is not possible");
    }
    private String[] getListeners() throws Exception {
        final ObjectName on         = new ObjectName(DNONS);
        final String op             = "dottedNameList";
        final String san            = (new String[]{}).getClass().getName();
        final String[] sign         = new String[]{san};
        final Object[] params       = new Object[]{new String[]{HTTP_LISTENER_LIST_DN}};
        final String[] values       = (String[])mbsc.invoke(on, op, params, sign);
        return ( values );
    }

    public long getExecutionTime() {
        return ( end - start );
    }
}

enum TestLogLevel {
    OFF,
    INFO,
    WARNING,
    SEVERE
}
