/*
 * Copyright 2018-present Open Networking Foundation
 *
 * 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.t3.impl;

import com.google.common.collect.ImmutableSet;
import org.onlab.packet.EthType;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.mcast.api.McastRouteData;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.t3.api.MulticastRouteNib;
import org.onosproject.t3.api.StaticPacketTrace;
import org.slf4j.Logger;

import java.util.Set;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Implementation of the generator class that yields a set of Packet Traces.
 */
public class McastGenerator extends Generator<Set<StaticPacketTrace>> {

    private static final Logger log = getLogger(McastGenerator.class);
    protected static final MacAddress IPV4_ADDRESS = MacAddress.valueOf("01:00:5E:00:00:00");
    protected static final MacAddress IPV6_ADDRESS = MacAddress.valueOf("33:33:00:00:00:00");
    private static final String NO_SINK = "There is no sink for this mcast route";
    private static final String GENERATOR_ERROR =
            "Generator for mcast route trace has benn interrupted. The trace result may be incomplete.";

    private final MulticastRouteNib mcastRouteNib;
    private final TroubleshootManager manager;
    private final VlanId vlanId;

    /**
     * Creates a generator for obtaining traces of all configured multicast routes.
     *
     * @param mcastRouteNib the multicast route NIB
     * @param manager the troubleshoot manager issuing the request.
     * @param vlanId  the multicast configured VlanId.
     */
    McastGenerator(MulticastRouteNib mcastRouteNib, TroubleshootManager manager, VlanId vlanId) {
        this.mcastRouteNib = mcastRouteNib;
        this.manager = manager;
        this.vlanId = vlanId;
    }

    @Override
    protected void run() {
        mcastRouteNib.getRoutes().forEach(route -> {
            McastRouteData routeData = mcastRouteNib.routeData(route);
            IpAddress group = route.group();
            routeData.sources().forEach((host, sources) -> {
                sources.forEach(source -> {
                    TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
                            .matchVlanId(vlanId)
                            .matchInPort(source.port());
                    if (group.isIp4()) {
                        selector.matchEthDst(IPV4_ADDRESS)
                                .matchIPDst(group.toIpPrefix())
                                .matchEthType(EthType.EtherType.IPV4.ethType().toShort());
                    } else {
                        selector.matchEthDst(IPV6_ADDRESS)
                                .matchIPv6Dst(group.toIpPrefix())
                                .matchEthType(EthType.EtherType.IPV6.ethType().toShort());
                    }

                    StaticPacketTrace trace;
                    // check this mcast route has no sink
                    if (routeData.allSinks().size() == 0) {
                        trace = new StaticPacketTrace(selector.build(), source);
                        trace.addResultMessage(NO_SINK);
                        // tracing mcast route with no sink is not a failure
                        trace.setSuccess(true);
                    } else {
                        trace = manager.trace(selector.build(), source);
                    }
                    try {
                        yield(ImmutableSet.of(trace));
                    } catch (InterruptedException e) {
                        log.warn("Interrupted generator", e.getMessage());
                        log.debug("exception", e);
                        trace.setSuccess(false);
                        trace.addResultMessage(GENERATOR_ERROR);
                    }
                });
            });
        });
    }
}
