/*
 * Copyright 2016-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.ospf.controller.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Sets;
import org.onosproject.net.driver.DriverService;
import org.onosproject.ospf.controller.OspfAgent;
import org.onosproject.ospf.controller.OspfController;
import org.onosproject.ospf.controller.OspfLinkListener;
import org.onosproject.ospf.controller.OspfLinkTed;
import org.onosproject.ospf.controller.OspfProcess;
import org.onosproject.ospf.controller.OspfRouter;
import org.onosproject.ospf.controller.OspfRouterListener;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Representation of an OSPF controller implementation.
 * Serves as a one stop shop for obtaining OSPF devices and (un)register listeners on OSPF events
 */
@Component(immediate = true, service = OspfController.class)
public class OspfControllerImpl implements OspfController {

    private static final Logger log = LoggerFactory.getLogger(OspfControllerImpl.class);
    private final Controller ctrl = new Controller();
    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected DriverService driverService;
    protected Set<OspfRouterListener> ospfRouterListener = new HashSet<>();
    protected Set<OspfLinkListener> ospfLinkListener = Sets.newHashSet();
    protected OspfAgent agent = new InternalDeviceConfig();

    @Activate
    public void activate() {
        log.info("OSPFControllerImpl activate...!!!");
        ctrl.start(agent, driverService);
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        ctrl.stop();
        log.info("Stopped");
    }


    @Override
    public void addRouterListener(OspfRouterListener listener) {
        if (!ospfRouterListener.contains(listener)) {
            this.ospfRouterListener.add(listener);
        }
    }

    @Override
    public void removeRouterListener(OspfRouterListener listener) {
        this.ospfRouterListener.remove(listener);
    }

    @Override
    public void addLinkListener(OspfLinkListener listener) {
        ospfLinkListener.add(listener);

    }

    @Override
    public void removeLinkListener(OspfLinkListener listener) {
        ospfLinkListener.remove(listener);

    }

    @Override
    public Set<OspfRouterListener> listener() {
        return ospfRouterListener;
    }

    @Override
    public Set<OspfLinkListener> linkListener() {
        return ospfLinkListener;
    }


    @Override
    public List<OspfProcess> getAllConfiguredProcesses() {
        List<OspfProcess> processes = ctrl.getAllConfiguredProcesses();
        return processes;
    }

    @Override
    public void updateConfig(JsonNode processesNode) {
        try {
            List<OspfProcess> ospfProcesses = OspfConfigUtil.processes(processesNode);
            //if there is interface details then update configuration
            if (!ospfProcesses.isEmpty() &&
                    ospfProcesses.get(0).areas() != null && !ospfProcesses.get(0).areas().isEmpty() &&
                    ospfProcesses.get(0).areas().get(0) != null &&
                    !ospfProcesses.get(0).areas().get(0).ospfInterfaceList().isEmpty()) {
                ctrl.updateConfig(ospfProcesses);
            }
        } catch (Exception e) {
            log.debug("Error::updateConfig::{}", e.getMessage());
        }
    }

    @Override
    public void deleteConfig(List<OspfProcess> processes, String attribute) {
    }

    /**
     * Notifier for internal OSPF device and link changes.
     */
    private class InternalDeviceConfig implements OspfAgent {

        @Override
        public boolean addConnectedRouter(OspfRouter ospfRouter) {
            for (OspfRouterListener l : listener()) {
                l.routerAdded(ospfRouter);
            }
            return true;
        }

        @Override
        public void removeConnectedRouter(OspfRouter ospfRouter) {
            for (OspfRouterListener l : listener()) {
                l.routerRemoved(ospfRouter);
            }
        }

        @Override
        public void addLink(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
            for (OspfLinkListener l : linkListener()) {
                l.addLink(ospfRouter, ospfLinkTed);
            }

        }

        @Override
        public void deleteLink(OspfRouter ospfRouter, OspfLinkTed ospfLinkTed) {
            for (OspfLinkListener l : linkListener()) {
                l.deleteLink(ospfRouter, ospfLinkTed);
            }
        }
    }
}