/*
 * Copyright 2017-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.artemis.impl;

import com.google.common.collect.Sets;
import io.netty.channel.ChannelHandlerContext;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.json.JSONObject;
import org.onlab.packet.IpPrefix;
import org.onosproject.artemis.ArtemisMonitor;
import org.onosproject.artemis.ArtemisPacketProcessor;
import org.onosproject.artemis.impl.objects.ArtemisMessage;
import org.onosproject.event.EventDeliveryService;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Component(immediate = true)
@Service
public class ArtemisMonitorImpl implements ArtemisMonitor {
    private final Logger log = LoggerFactory.getLogger(getClass());
    private static final Class<ArtemisConfig> CONFIG_CLASS = ArtemisConfig.class;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected EventDeliveryService eventDispatcher;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    private NetworkConfigService configService;

    /* Variables */
    private Set<PrefixHandler> prefixHandlers = Sets.newHashSet();
    private InternalPacketProcessor packetProcessor = new InternalPacketProcessor();

    private final InternalNetworkConfigListener configListener =
            new InternalNetworkConfigListener();

    @Activate
    protected void activate() {
        configService.addListener(configListener);
        log.info("Artemis Monitor Service Started");
    }

    @Deactivate
    protected void deactivate() {
        configService.removeListener(configListener);
        prefixHandlers.forEach(PrefixHandler::stopPrefixMonitors);
        prefixHandlers.clear();

        log.info("Artemis Monitor Service Stopped");
    }

    private class InternalPacketProcessor implements ArtemisPacketProcessor {

        @Override
        public void processMoasPacket(ArtemisMessage msg, ChannelHandlerContext ctx) {

        }

        @Override
        public void processMonitorPacket(JSONObject msg) {
            // TODO: in future maybe store the BGP Update message and propagate it to the cluster instead of Events
            eventDispatcher.post(new ArtemisEvent(ArtemisEvent.Type.BGPUPDATE_ADDED, msg));
        }
    }

    private class InternalNetworkConfigListener implements NetworkConfigListener {

        @Override
        public void event(NetworkConfigEvent event) {
            switch (event.type()) {
                case CONFIG_REGISTERED:
                case CONFIG_UNREGISTERED: {
                    break;
                }
                case CONFIG_REMOVED: {
                    if (event.configClass() == CONFIG_CLASS) {
                        prefixHandlers.forEach(PrefixHandler::stopPrefixMonitors);
                        prefixHandlers.clear();
                    }
                    break;
                }
                case CONFIG_UPDATED:
                case CONFIG_ADDED: {
                    if (event.configClass() == CONFIG_CLASS) {
                        event.config().ifPresent(config -> {
                            ArtemisConfig artemisConfig = (ArtemisConfig) config;
                            Set<IpPrefix> ipPrefixes = artemisConfig.prefixesToMonitor();
                            Map<String, Set<String>> monitors = artemisConfig.activeMonitors();

                            prefixHandlers.forEach(PrefixHandler::stopPrefixMonitors);
                            prefixHandlers.clear();
                            prefixHandlers = ipPrefixes.stream()
                                    .map(prefix -> new PrefixHandler(prefix, monitors, packetProcessor))
                                    .collect(Collectors.toSet());

                            prefixHandlers.forEach(PrefixHandler::startPrefixMonitors);
                        });
                    }
                    break;
                }
                default:
                    break;
            }
        }

    }
}
