/*
 * 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 flex.management.runtime.messaging.services.http;

import java.util.Date;

import flex.management.BaseControl;
import flex.management.runtime.AdminConsoleTypes;
import flex.management.runtime.messaging.DestinationControl;
import flex.messaging.services.http.HTTPProxyDestination;

/**
 * The <code>HTTPProxyDestinationControl</code> class is the MBean implementation for
 * monitoring and managing a <code>HTTPProxyDestination</code> at runtime.
 */
public class HTTPProxyDestinationControl extends DestinationControl
        implements HTTPProxyDestinationControlMBean {
    private static final String TYPE = "HTTPProxyDestination";

    private int invokeSOAPCount = 0;
    private Date lastInvokeSOAPTimestamp;
    private long invokeSOAPStart;
    private int invokeHTTPCount = 0;
    private Date lastInvokeHTTPTimestamp;
    private long invokeHTTPStart;

    /**
     * Constructs a new <code>HTTPProxyDestinationControl</code> instance.
     *
     * @param destination The <code>HTTPProxyDestination</code> managed by this MBean.
     * @param parent      The parent MBean in the management hierarchy.
     */
    public HTTPProxyDestinationControl(HTTPProxyDestination destination, BaseControl parent) {
        super(destination, parent);
        invokeSOAPStart = System.currentTimeMillis();
        invokeHTTPStart = invokeSOAPStart;
    }

    /**
     * {@inheritDoc}
     */
    protected void onRegistrationComplete() {
        super.onRegistrationComplete();

        String name = this.getObjectName().getCanonicalName();

        String[] pollablePerInterval = {"InvokeHTTPCount", "InvokeSOAPCount"};
        String[] pollableGeneral = {"InvokeHTTPFrequency", "InvokeSOAPFrequency"};
        String[] destinationGeneral = {"LastInvokeHTTPTimestamp", "LastInvokeSOAPTimestamp"};

        getRegistrar().registerObjects(
                new int[]{AdminConsoleTypes.DESTINATION_POLLABLE, AdminConsoleTypes.GRAPH_BY_POLL_INTERVAL},
                name, pollablePerInterval);
        getRegistrar().registerObjects(AdminConsoleTypes.DESTINATION_POLLABLE, name,
                pollableGeneral);
        getRegistrar().registerObjects(AdminConsoleTypes.DESTINATION_GENERAL, name,
                destinationGeneral);
    }

    /**
     * (non-Javadoc)
     *
     * @see flex.management.runtime.HTTPProxyServiceControlMBean#getInvokeSOAPCount()
     */
    public Integer getInvokeSOAPCount() {
        return new Integer(invokeSOAPCount);
    }

    /**
     * (non-Javadoc)
     *
     * @see flex.management.runtime.HTTPProxyServiceControlMBean#resetInvokeSOAPCount()
     */
    public void resetInvokeSOAPCount() {
        invokeSOAPStart = System.currentTimeMillis();
        invokeSOAPCount = 0;
        lastInvokeSOAPTimestamp = null;
    }

    /**
     * Increments the count of Soap invocations.
     */
    public void incrementInvokeSOAPCount() {
        ++invokeSOAPCount;
        lastInvokeSOAPTimestamp = new Date();
    }

    /**
     * (non-Javadoc)
     *
     * @see flex.management.runtime.HTTPProxyServiceControlMBean#getLastInvokeSOAPTimestamp()
     */
    public Date getLastInvokeSOAPTimestamp() {
        return lastInvokeSOAPTimestamp;
    }

    /**
     * (non-Javadoc)
     *
     * @see flex.management.runtime.HTTPProxyServiceControlMBean#getInvokeSOAPFrequency()
     */
    public Double getInvokeSOAPFrequency() {
        if (invokeSOAPCount > 0) {
            double runtime = differenceInMinutes(invokeSOAPStart, System.currentTimeMillis());
            return new Double(invokeSOAPCount / runtime);
        } else {
            return new Double(0);
        }
    }

    /**
     * (non-Javadoc)
     *
     * @see flex.management.runtime.HTTPProxyServiceControlMBean#getInvokeHTTPCount()
     */
    public Integer getInvokeHTTPCount() {
        return new Integer(invokeHTTPCount);
    }

    /**
     * (non-Javadoc)
     *
     * @see flex.management.runtime.HTTPProxyServiceControlMBean#resetInvokeHTTPCount()
     */
    public void resetInvokeHTTPCount() {
        invokeHTTPStart = System.currentTimeMillis();
        invokeHTTPCount = 0;
        lastInvokeHTTPTimestamp = null;
    }

    /**
     * Increments the count of HTTP invocations.
     */
    public void incrementInvokeHTTPCount() {
        ++invokeHTTPCount;
        lastInvokeHTTPTimestamp = new Date();
    }

    /**
     * (non-Javadoc)
     *
     * @see flex.management.runtime.HTTPProxyServiceControlMBean#getLastInvokeHTTPTimestamp()
     */
    public Date getLastInvokeHTTPTimestamp() {
        return lastInvokeHTTPTimestamp;
    }

    /**
     * (non-Javadoc)
     *
     * @see flex.management.runtime.HTTPProxyServiceControlMBean#getInvokeHTTPFrequency()
     */
    public Double getInvokeHTTPFrequency() {
        if (invokeHTTPCount > 0) {
            double runtime = differenceInMinutes(invokeHTTPStart, System.currentTimeMillis());
            return new Double(invokeHTTPCount / runtime);
        } else {
            return new Double(0);
        }
    }

    /**
     * (non-Javadoc)
     *
     * @see flex.management.BaseControlMBean#getType()
     */
    public String getType() {
        return TYPE;
    }
}
