/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed 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.onosproject.mcast;

import org.onosproject.event.AbstractEvent;
import org.onosproject.net.ConnectPoint;

import java.util.Optional;

/**
 * An entity representing a multicast event. Event either add or remove
 * sinks or sources.
 */
public class McastEvent extends AbstractEvent<McastEvent.Type, McastRoute> {

    private final Optional<ConnectPoint> sink;
    private final Optional<ConnectPoint> source;

    public enum Type {
        /**
         * A new mcast route has been added.
         */
        ROUTE_ADDED,

        /**
         * A mcast route has been removed.
         */
        ROUTE_REMOVED,

        /**
         * A source for a mcast route (ie. the subject) has been added.
         */
        SOURCE_ADDED,

        /**
         * A source for a mcast route (ie. the subject) has been removed.
         */
        SOURCE_REMOVED,

        /**
         * A sink for a mcast route (ie. the subject) has been added.
         */
        SINK_ADDED,

        /**
         * A source for a mcast route (ie. the subject) has been removed.
         */
        SINK_REMOVED
    }

    private McastEvent(McastEvent.Type type, McastRoute subject) {
        super(type, subject);
        sink = Optional.empty();
        source = Optional.empty();
    }

    private McastEvent(McastEvent.Type type, McastRoute subject, long time) {
        super(type, subject, time);
        sink = Optional.empty();
        source = Optional.empty();
    }

    protected McastEvent(McastEvent.Type type, McastRoute subject,
                       ConnectPoint sink,
                       ConnectPoint source) {
        super(type, subject);
        this.sink = Optional.ofNullable(sink);
        this.source = Optional.ofNullable(source);
    }

    protected McastEvent(McastEvent.Type type, McastRoute subject, long time,
                       ConnectPoint sink,
                       ConnectPoint source) {
        super(type, subject, time);
        this.sink = Optional.ofNullable(sink);
        this.source = Optional.ofNullable(source);
    }

    /**
     * The sink which has been removed or added. The field may not be set
     * if the sink has not been detected yet or has been removed.
     *
     * @return an optional connect point
     */
    public Optional<ConnectPoint> sink() {
        return sink;
    }

    /**
     * The source which has been removed or added. The field may not be set
     * if the source has not been detected yet or has been removed.

     * @return an optional connect point
     */
    public Optional<ConnectPoint> source() {
        return source;
    }
}
