/*
 * 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.cassandra.streaming.management;

import java.util.concurrent.atomic.AtomicLong;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;

import org.apache.cassandra.streaming.*;

/**
 */
public class StreamEventJMXNotifier extends NotificationBroadcasterSupport implements StreamEventHandler
{
    // interval in millisec to use for progress notification
    private static final long PROGRESS_NOTIFICATION_INTERVAL = 1000;

    private final AtomicLong seq = new AtomicLong();

    private long progressLastSent;

    public void handleStreamEvent(StreamEvent event)
    {
        Notification notif = null;
        switch (event.eventType)
        {
            case STREAM_PREPARED:
                notif = new Notification(StreamEvent.SessionPreparedEvent.class.getCanonicalName(),
                                                StreamManagerMBean.OBJECT_NAME,
                                                seq.getAndIncrement());
                notif.setUserData(SessionInfoCompositeData.toCompositeData(event.planId, ((StreamEvent.SessionPreparedEvent) event).session));
                break;
            case STREAM_COMPLETE:
                notif = new Notification(StreamEvent.SessionCompleteEvent.class.getCanonicalName(),
                                                StreamManagerMBean.OBJECT_NAME,
                                                seq.getAndIncrement());
                notif.setUserData(SessionCompleteEventCompositeData.toCompositeData((StreamEvent.SessionCompleteEvent) event));
                break;
            case FILE_PROGRESS:
                ProgressInfo progress = ((StreamEvent.ProgressEvent) event).progress;
                long current = System.currentTimeMillis();
                if (current - progressLastSent >= PROGRESS_NOTIFICATION_INTERVAL || progress.isCompleted())
                {
                    notif = new Notification(StreamEvent.ProgressEvent.class.getCanonicalName(),
                                             StreamManagerMBean.OBJECT_NAME,
                                             seq.getAndIncrement());
                    notif.setUserData(ProgressInfoCompositeData.toCompositeData(event.planId, progress));
                    progressLastSent = System.currentTimeMillis();
                }
                else
                {
                    return;
                }
                break;
        }
        sendNotification(notif);
    }

    public void onSuccess(StreamState result)
    {
        Notification notif = new Notification(StreamEvent.class.getCanonicalName() + ".success",
                                              StreamManagerMBean.OBJECT_NAME,
                                              seq.getAndIncrement());
        notif.setUserData(StreamStateCompositeData.toCompositeData(result));
        sendNotification(notif);
    }

    public void onFailure(Throwable t)
    {
        Notification notif = new Notification(StreamEvent.class.getCanonicalName() + ".failure",
                                              StreamManagerMBean.OBJECT_NAME,
                                              seq.getAndIncrement());
        notif.setUserData(t.fillInStackTrace().toString());
        sendNotification(notif);
    }
}
