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

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.Port;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.basics.BasicDeviceConfig;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.link.LinkService;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import static com.google.common.base.Strings.emptyToNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.apache.commons.lang.WordUtils.capitalizeFully;
import static org.onosproject.net.DeviceId.deviceId;

/**
 * Message handler for device view related messages.
 */
public class DeviceViewMessageHandler extends UiMessageHandler {

    private static final String DEV_DATA_REQ = "deviceDataRequest";
    private static final String DEV_DATA_RESP = "deviceDataResponse";
    private static final String DEVICES = "devices";

    private static final String DEV_DETAILS_REQ = "deviceDetailsRequest";
    private static final String DEV_DETAILS_RESP = "deviceDetailsResponse";
    private static final String DETAILS = "details";

    private static final String DEV_NAME_CHANGE_REQ = "deviceNameChangeRequest";
    private static final String DEV_NAME_CHANGE_RESP = "deviceNameChangeResponse";

    private static final String ID = "id";
    private static final String TYPE = "type";
    private static final String AVAILABLE = "available";
    private static final String AVAILABLE_IID = "_iconid_available";
    private static final String TYPE_IID = "_iconid_type";
    private static final String DEV_ICON_PREFIX = "devIcon_";
    private static final String NUM_PORTS = "num_ports";
    private static final String LINK_DEST = "elinks_dest";
    private static final String MFR = "mfr";
    private static final String HW = "hw";
    private static final String SW = "sw";
    private static final String PROTOCOL = "protocol";
    private static final String MASTER_ID = "masterid";
    private static final String CHASSIS_ID = "chassisid";
    private static final String SERIAL = "serial";
    private static final String PORTS = "ports";
    private static final String ENABLED = "enabled";
    private static final String SPEED = "speed";
    private static final String NAME = "name";


    private static final String[] COL_IDS = {
            AVAILABLE, AVAILABLE_IID, TYPE_IID, ID,
            NUM_PORTS, MASTER_ID, MFR, HW, SW,
            PROTOCOL, CHASSIS_ID, SERIAL
    };

    private static final String ICON_ID_ONLINE = "active";
    private static final String ICON_ID_OFFLINE = "inactive";

    @Override
    protected Collection<RequestHandler> createRequestHandlers() {
        return ImmutableSet.of(
                new DataRequestHandler(),
                new NameChangeHandler(),
                new DetailRequestHandler()
        );
    }

    private static String getTypeIconId(Device d) {
        return DEV_ICON_PREFIX + d.type().toString();
    }

    // handler for device table requests
    private final class DataRequestHandler extends TableRequestHandler {
        private DataRequestHandler() {
            super(DEV_DATA_REQ, DEV_DATA_RESP, DEVICES);
        }

        @Override
        protected String[] getColumnIds() {
            return COL_IDS;
        }

        @Override
        protected void populateTable(TableModel tm, ObjectNode payload) {
            DeviceService ds = get(DeviceService.class);
            MastershipService ms = get(MastershipService.class);
            for (Device dev : ds.getDevices()) {
                populateRow(tm.addRow(), dev, ds, ms);
            }
        }

        private void populateRow(TableModel.Row row, Device dev,
                                 DeviceService ds, MastershipService ms) {
            DeviceId id = dev.id();
            boolean available = ds.isAvailable(id);
            String iconId = available ? ICON_ID_ONLINE : ICON_ID_OFFLINE;

            String protocol = dev.annotations().value(PROTOCOL);

            row.cell(ID, id)
                .cell(AVAILABLE, available)
                .cell(AVAILABLE_IID, iconId)
                .cell(TYPE_IID, getTypeIconId(dev))
                .cell(MFR, dev.manufacturer())
                .cell(HW, dev.hwVersion())
                .cell(SW, dev.swVersion())
                .cell(PROTOCOL, protocol != null ? protocol : "")
                .cell(NUM_PORTS, ds.getPorts(id).size())
                .cell(MASTER_ID, ms.getMasterFor(id));
        }
    }

    // handler for selected device detail requests
    private final class DetailRequestHandler extends RequestHandler {
        private DetailRequestHandler() {
            super(DEV_DETAILS_REQ);
        }

        @Override
        public void process(long sid, ObjectNode payload) {
            String id = string(payload, "id", "of:0000000000000000");

            DeviceId deviceId = deviceId(id);
            DeviceService service = get(DeviceService.class);
            MastershipService ms = get(MastershipService.class);
            Device device = service.getDevice(deviceId);
            ObjectNode data = MAPPER.createObjectNode();

            data.put(ID, deviceId.toString());

            // Get friendly name of the device from the annotations
            String name = device.annotations().value(AnnotationKeys.NAME);
            data.put(NAME, isNullOrEmpty(name) ? deviceId.toString() : name);

            data.put(TYPE, capitalizeFully(device.type().toString()));
            data.put(TYPE_IID, getTypeIconId(device));
            data.put(MFR, device.manufacturer());
            data.put(HW, device.hwVersion());
            data.put(SW, device.swVersion());
            data.put(SERIAL, device.serialNumber());
            data.put(CHASSIS_ID, device.chassisId().toString());
            data.put(MASTER_ID, ms.getMasterFor(deviceId).toString());
            data.put(PROTOCOL, device.annotations().value(PROTOCOL));

            ArrayNode ports = MAPPER.createArrayNode();

            List<Port> portList = new ArrayList<>(service.getPorts(deviceId));
            Collections.sort(portList, (p1, p2) -> {
                long delta = p1.number().toLong() - p2.number().toLong();
                return delta == 0 ? 0 : (delta < 0 ? -1 : +1);
            });

            for (Port p : portList) {
                ports.add(portData(p, deviceId));
            }
            data.set(PORTS, ports);

            ObjectNode rootNode = MAPPER.createObjectNode();
            rootNode.set(DETAILS, data);
            sendMessage(DEV_DETAILS_RESP, 0, rootNode);
        }

        private ObjectNode portData(Port p, DeviceId id) {
            ObjectNode port = MAPPER.createObjectNode();
            LinkService ls = get(LinkService.class);
            String name = p.annotations().value(AnnotationKeys.PORT_NAME);

            port.put(ID, capitalizeFully(p.number().toString()));
            port.put(TYPE, capitalizeFully(p.type().toString()));
            port.put(SPEED, p.portSpeed());
            port.put(ENABLED, p.isEnabled());
            port.put(NAME, name != null ? name : "");

            Set<Link> links = ls.getEgressLinks(new ConnectPoint(id, p.number()));
            if (!links.isEmpty()) {
                StringBuilder egressLinks = new StringBuilder();
                for (Link l : links) {
                    ConnectPoint dest = l.dst();
                    egressLinks.append(dest.elementId()).append("/")
                            .append(dest.port()).append(" ");
                }
                port.put(LINK_DEST, egressLinks.toString());
            }

            return port;
        }
    }

    // handler for changing device friendly name
    private final class NameChangeHandler extends RequestHandler {
        private NameChangeHandler() {
            super(DEV_NAME_CHANGE_REQ);
        }

        @Override
        public void process(long sid, ObjectNode payload) {
            DeviceId deviceId = deviceId(string(payload, "id", "of:0000000000000000"));
            NetworkConfigService service = get(NetworkConfigService.class);
            BasicDeviceConfig cfg = service.getConfig(deviceId, BasicDeviceConfig.class);

            // Name attribute missing (or being empty) from the payload means
            // that the friendly name should be unset.
            cfg.name(emptyToNull(string(payload, "name", null)));
            cfg.apply();
            sendMessage(DEV_NAME_CHANGE_RESP, 0, payload);
        }
    }
}
