/*
 * 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.catalina.mbeans;

import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.RuntimeOperationsException;
import javax.management.modelmbean.InvalidTargetObjectTypeException;

import org.apache.catalina.Executor;
import org.apache.catalina.Service;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.modeler.BaseModelMBean;

public class ServiceMBean extends BaseModelMBean {

    public ServiceMBean()
        throws MBeanException, RuntimeOperationsException {

        super();

    }

    /**
     * Add a new Connector to the set of defined Connectors, and associate it
     * with this Service's Container.
     *
     * @param address The IP address on which to bind
     * @param port TCP port number to listen on
     * @param isAjp Create a AJP/1.3 Connector
     * @param isSSL Create a secure Connector
     *
     * @throws MBeanException error creating the connector
     */
    public void addConnector(String address, int port, boolean isAjp, boolean isSSL) throws MBeanException {

        Service service;
        try {
            service = (Service)getManagedResource();
        } catch (InstanceNotFoundException e) {
            throw new MBeanException(e);
        } catch (RuntimeOperationsException e) {
            throw new MBeanException(e);
        } catch (InvalidTargetObjectTypeException e) {
            throw new MBeanException(e);
        }
        String protocol = isAjp ? "AJP/1.3" : "HTTP/1.1";
        Connector connector = new Connector(protocol);
        if ((address!=null) && (address.length()>0)) {
            connector.setProperty("address", address);
        }
        connector.setPort(port);
        connector.setSecure(isSSL);
        connector.setScheme(isSSL ? "https" : "http");

        service.addConnector(connector);

    }

    /**
     * Adds a named executor to the service
     * @param type Classname of the Executor to be added
     * @throws MBeanException error creating the executor
     */
    public void addExecutor(String type) throws MBeanException {

        Service service;
        try {
            service = (Service)getManagedResource();
        } catch (InstanceNotFoundException e) {
            throw new MBeanException(e);
        } catch (RuntimeOperationsException e) {
            throw new MBeanException(e);
        } catch (InvalidTargetObjectTypeException e) {
            throw new MBeanException(e);
        }

        Executor executor;
        try {
             executor = (Executor)Class.forName(type).getConstructor().newInstance();
        } catch (ReflectiveOperationException e) {
            throw new MBeanException(e);
        }

        service.addExecutor(executor);

    }

    /**
     * Find and return the set of Connectors associated with this Service.
     * @return an array of string representations of the connectors
     * @throws MBeanException error accessing the associated service
     */
    public String[] findConnectors() throws MBeanException {

        Service service;
        try {
            service = (Service)getManagedResource();
        } catch (InstanceNotFoundException e) {
            throw new MBeanException(e);
        } catch (RuntimeOperationsException e) {
            throw new MBeanException(e);
        } catch (InvalidTargetObjectTypeException e) {
            throw new MBeanException(e);
        }

        Connector[] connectors = service.findConnectors();
        String[] str = new String[connectors.length];

        for(int i=0; i< connectors.length; i++){
            str[i] = connectors[i].toString();
        }

        return str;

    }

    /**
     * Retrieves all executors.
     * @return an array of string representations of the executors
     * @throws MBeanException error accessing the associated service
     */
    public String[] findExecutors() throws MBeanException {

        Service service;
        try {
            service = (Service)getManagedResource();
        } catch (InstanceNotFoundException e) {
            throw new MBeanException(e);
        } catch (RuntimeOperationsException e) {
            throw new MBeanException(e);
        } catch (InvalidTargetObjectTypeException e) {
            throw new MBeanException(e);
        }

        Executor[] executors = service.findExecutors();
        String[] str = new String[executors.length];

        for(int i=0; i< executors.length; i++){
            str[i] = executors[i].toString();
        }

        return str;
    }

    /**
     * Retrieves executor by name
     * @param name Name of the executor to be retrieved
     * @return a string representation of the executor
     * @throws MBeanException error accessing the associated service
     */
    public String getExecutor(String name) throws MBeanException{

        Service service;
        try {
            service = (Service)getManagedResource();
        } catch (InstanceNotFoundException e) {
            throw new MBeanException(e);
        } catch (RuntimeOperationsException e) {
            throw new MBeanException(e);
        } catch (InvalidTargetObjectTypeException e) {
            throw new MBeanException(e);
        }

        Executor executor = service.getExecutor(name);
        return executor.toString();

    }

}
