/*
 * 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.grouphandler;

import static org.slf4j.LoggerFactory.getLogger;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

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.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.group.GroupService;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.link.LinkListener;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.topology.TopologyService;
import org.slf4j.Logger;

/**
 * Sample application to verify group subsystem end to end.
 * This application expects a network of maximum of six connected
 * devices for the test to work. For every device in the network,
 * this test application launches a default group handler function
 * that creates ECMP groups for every neighbor the device is
 * connected to.
 */
@Component(immediate = true)
public class DefaultGroupHandlerApp {

    private final Logger log = getLogger(getClass());

    private final DeviceProperties config = new DeviceConfiguration();
    private ApplicationId appId;
    private HashMap<DeviceId, DefaultGroupHandler> dghMap =
            new HashMap<DeviceId, DefaultGroupHandler>();

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected TopologyService topologyService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceService deviceService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected LinkService linkService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected GroupService groupService;
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

    private DeviceListener deviceListener = new InternalDeviceListener();
    private LinkListener linkListener = new InternalLinkListener();

    @Activate
    public void activate() {
        appId = coreService.registerApplication("org.onosproject.defaultgrouphandler");
        log.info("DefaultGroupHandlerApp Activating");
        deviceService.addListener(deviceListener);
        linkService.addListener(linkListener);
        for (Device device: deviceService.getDevices()) {
            log.debug("Initiating default group handling for {}", device.id());
            DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(device.id(),
                                                              appId,
                                                              config,
                                                              linkService,
                                                              groupService);
            dgh.createGroups();
            dghMap.put(device.id(), dgh);
        }
        log.info("Activated");
    }

    @Deactivate
    public void deactivate() {
        dghMap.clear();
    }

    public class DeviceConfiguration implements DeviceProperties {
        private final List<Integer> allSegmentIds =
                Arrays.asList(101, 102, 103, 104, 105, 106);
        private HashMap<DeviceId, Integer> deviceSegmentIdMap =
                new HashMap<DeviceId, Integer>() {
            {
                put(DeviceId.deviceId("of:0000000000000001"), 101);
                put(DeviceId.deviceId("of:0000000000000002"), 102);
                put(DeviceId.deviceId("of:0000000000000003"), 103);
                put(DeviceId.deviceId("of:0000000000000004"), 104);
                put(DeviceId.deviceId("of:0000000000000005"), 105);
                put(DeviceId.deviceId("of:0000000000000006"), 106);
            }
        };
        private final HashMap<DeviceId, MacAddress> deviceMacMap =
                new HashMap<DeviceId, MacAddress>() {
            {
                put(DeviceId.deviceId("of:0000000000000001"),
                     MacAddress.valueOf("00:00:00:00:00:01"));
                put(DeviceId.deviceId("of:0000000000000002"),
                     MacAddress.valueOf("00:00:00:00:00:02"));
                put(DeviceId.deviceId("of:0000000000000003"),
                     MacAddress.valueOf("00:00:00:00:00:03"));
                put(DeviceId.deviceId("of:0000000000000004"),
                     MacAddress.valueOf("00:00:00:00:00:04"));
                put(DeviceId.deviceId("of:0000000000000005"),
                     MacAddress.valueOf("00:00:00:00:00:05"));
                put(DeviceId.deviceId("of:0000000000000006"),
                     MacAddress.valueOf("00:00:00:00:00:06"));
            }
        };

        @Override
        public int getSegmentId(DeviceId deviceId) {
            if (deviceSegmentIdMap.get(deviceId) != null) {
                log.debug("getSegmentId for device{} is {}",
                          deviceId,
                          deviceSegmentIdMap.get(deviceId));
                return deviceSegmentIdMap.get(deviceId);
            } else {
                throw new IllegalStateException();
            }
        }
        @Override
        public MacAddress getDeviceMac(DeviceId deviceId) {
            if (deviceMacMap.get(deviceId) != null) {
                log.debug("getDeviceMac for device{} is {}",
                          deviceId,
                          deviceMacMap.get(deviceId));
                return deviceMacMap.get(deviceId);
            } else {
                throw new IllegalStateException();
            }
        }
        @Override
        public boolean isEdgeDevice(DeviceId deviceId) {
            return true;
        }
        @Override
        public List<Integer> getAllDeviceSegmentIds() {
            return allSegmentIds;
        }
    }

    private class InternalDeviceListener implements DeviceListener {

        @Override
        public void event(DeviceEvent event) {
            switch (event.type()) {
            case DEVICE_ADDED:
                log.debug("Initiating default group handling for {}", event.subject().id());
                DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(
                                                                  event.subject().id(),
                                                                  appId,
                                                                  config,
                                                                  linkService,
                                                                  groupService);
                dgh.createGroups();
                dghMap.put(event.subject().id(), dgh);
                break;
            case PORT_REMOVED:
                if (dghMap.get(event.subject().id()) != null) {
                    dghMap.get(event.subject().id()).portDown(event.port().number());
                }
                break;
            default:
                break;
            }

        }
    }

    private class InternalLinkListener implements LinkListener {

        @Override
        public void event(LinkEvent event) {
            switch (event.type()) {
            case LINK_ADDED:
                if (dghMap.get(event.subject().src().deviceId()) != null) {
                    dghMap.get(event.subject().src().deviceId()).linkUp(event.subject());
                }
                break;
            default:
                break;
            }
        }

    }
}