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


import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Annotations;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.resource.ContinuousResource;
import org.onosproject.net.resource.ResourceService;
import org.onosproject.net.resource.Resource;
import org.onosproject.net.resource.DiscreteResource;
import org.onosproject.net.resource.Resources;
import org.onosproject.ui.UiTopoOverlay;
import org.onosproject.ui.topo.PropertyPanel;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.ui.topo.TopoConstants.CoreButtons;
import org.onosproject.cli.AbstractShellCommand;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
/**
 * PCE WEB topology overlay.
 */
public class PceWebTopovOverlay extends UiTopoOverlay {

    // NOTE: this must match the ID defined in pcewebTopovOverlay.js
    private static final String OVERLAY_ID = "PCE-web-overlay";
    private static final String MY_TITLE = "Device details";

    public static final String AS_NUMBER = "asNumber";
    public static final String LSR_ID = "lsrId";
    public static final String ABR_BIT = "abrBit";
    public static final String ASBR_BIT = "externalBit";
    public static final String TE_METRIC = "teCost";
    public static final String ABR = "ABR";
    public static final String ASBR = "ASBR";
    public static final String ABR_ASBR = "ABR/ASBR";
    public static final String INNER = "Inner";
    public static final long IDENTIFIER_SET = 0x100000000L;
    public static final long SET = 0xFFFFFFFFL;
    public static final String TYPE_LABEL = "Type";
    public static final String AS_NUMBER_LABEL = "AS Number";
    public static final String LSR_ID_LABEL = "LSR ID";
    public static final String POSITION_LABEL = "Position";

    /**
     * Initialize the overlay ID.
     */
    public PceWebTopovOverlay() {
        super(OVERLAY_ID);
    }

    @Override
    public void deactivate() {
        super.deactivate();
        log.debug("Deactivated");
    }

    @Override
    public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) {

         pp.title(MY_TITLE);
         DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
         pp.removeAllProps();
         pp.removeButtons(CoreButtons.SHOW_PORT_VIEW)
                .removeButtons(CoreButtons.SHOW_GROUP_VIEW)
                .removeButtons(CoreButtons.SHOW_METER_VIEW);

         if (deviceService != null) {

            Device device = deviceService.getDevice(deviceId);
            Annotations annots = device.annotations();

            String type = annots.value(AnnotationKeys.TYPE);
            String asNumber = annots.value(AS_NUMBER);
            String lsrId = annots.value(LSR_ID);
            String abrStatus = annots.value(ABR_BIT);
            String asbrStatus = annots.value(ASBR_BIT);

            if (type != null) {
                pp.addProp(TYPE_LABEL, TYPE_LABEL, type);
            }

            if (asNumber != null) {
                pp.addProp(AS_NUMBER_LABEL, AS_NUMBER_LABEL, asNumber);
            }

            if (lsrId != null) {
                pp.addProp(LSR_ID_LABEL, LSR_ID_LABEL, lsrId);
            }

            if (Boolean.valueOf(abrStatus).equals(true) && Boolean.valueOf(asbrStatus).equals(true)) {
                pp.addProp(POSITION_LABEL, POSITION_LABEL, ABR_ASBR);
            } else if (Boolean.valueOf(abrStatus).equals(true)) {
                pp.addProp(POSITION_LABEL, POSITION_LABEL, ABR);
            } else if (Boolean.valueOf(asbrStatus).equals(true)) {
                pp.addProp(POSITION_LABEL, POSITION_LABEL, ASBR);
            } else {
                pp.addProp(POSITION_LABEL, POSITION_LABEL, INNER);
            }
        }
    }

    @Override
    public Map<String, String> additionalLinkData(LinkEvent event) {
        Map<String, String> map = new HashMap<>();
        Link link = event.subject();
        long srcPortNo;
        long dstPortNo;
        IpAddress ipDstAddress = null;
        IpAddress ipSrcAddress = null;
        String srcPort;
        String dstPort;
        String bandWidth;

        srcPortNo = link.src().port().toLong();
        if (((srcPortNo & IDENTIFIER_SET) == IDENTIFIER_SET)) {
            srcPort = String.valueOf(srcPortNo);
        } else {
            ipSrcAddress = Ip4Address.valueOf((int) srcPortNo);
            srcPort = ipSrcAddress.toString();
        }

        dstPortNo = link.dst().port().toLong();
        if (((dstPortNo & IDENTIFIER_SET) == IDENTIFIER_SET)) {
            dstPort = String.valueOf(dstPortNo);
        } else {
            ipDstAddress = Ip4Address.valueOf((int) dstPortNo);
            dstPort = ipDstAddress.toString();
        }

        map.put("Src Address", srcPort);
        map.put("Dst Address", dstPort);
        map.put("Te metric", link.annotations().value(TE_METRIC));

        ResourceService resService = AbstractShellCommand.get(ResourceService.class);
        DiscreteResource devResource = Resources.discrete(link.src().deviceId(), link.src().port()).resource();
        if (resService == null) {
            log.warn("resource service does not exist");
            return map;
        }

        if (devResource == null) {
            log.warn("Device resources does not exist");
            return map;
        }
        double regBandwidth = 0;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            log.error("Exception occurred while getting the bandwidth.");
            Thread.currentThread().interrupt();
        }
        Set<Resource> resources = resService.getRegisteredResources(devResource.id());
        for (Resource res : resources) {
            if (res instanceof ContinuousResource) {
                regBandwidth = ((ContinuousResource) res).value();
                break;
            }
        }

        if (regBandwidth != 0) {
            bandWidth = String.valueOf(regBandwidth);
            map.put("Bandwidth", bandWidth);
        }

        return map;
    }
}
