/*
 * Copyright 2015-present 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.joda.time.DateTime;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.Device;
import org.onosproject.net.device.DeviceService;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;
import org.onosproject.ui.table.cell.TimeFormatter;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import static com.google.common.collect.ImmutableList.copyOf;


/**
 * Message handler for cluster view related messages.
 */
public class ClusterViewMessageHandler extends UiMessageHandler {

    private static final String CLUSTER_DATA_REQ = "clusterDataRequest";
    private static final String CLUSTER_DATA_RESP = "clusterDataResponse";
    private static final String CLUSTERS = "clusters";

    private static final String CLUSTER_DETAILS_REQ = "clusterDetailsRequest";
    private static final String CLUSTER_DETAILS_RESP = "clusterDetailsResponse";
    private static final String DETAILS = "details";

    private static final String DEVICES = "devices";
    private static final String ID = "id";
    private static final String IP = "ip";
    private static final String TCP_PORT = "tcp";
    private static final String STATE_IID = "_iconid_state";
    private static final String STARTED_IID = "_iconid_started";
    private static final String UPDATED = "updated";

    private static final String[] COL_IDS = {
            ID, IP, TCP_PORT, STATE_IID, STARTED_IID, UPDATED
    };

    private static final String URI = "id";
    private static final String TYPE = "type";
    private static final String CHASSIS_ID = "chassisid";
    private static final String HW = "hw";
    private static final String SW = "sw";
    private static final String MFR = "mfr";
    private static final String PROTOCOL = "protocol";
    private static final String SERIAL = "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 ClusterDataRequest(),
                new DetailRequestHandler());
    }

    // handler for cluster table requests
    private final class ClusterDataRequest extends TableRequestHandler {
        private static final String NO_ROWS_MESSAGE = "No cluster nodes found";

        private ClusterDataRequest() {
            super(CLUSTER_DATA_REQ, CLUSTER_DATA_RESP, CLUSTERS);
        }

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

        @Override
        protected String noRowsMessage(ObjectNode payload) {
            return NO_ROWS_MESSAGE;
        }

        @Override
        protected TableModel createTableModel() {
            TableModel tm = super.createTableModel();
            tm.setFormatter(UPDATED, new TimeFormatter());
            return tm;
        }

        @Override
        protected void populateTable(TableModel tm, ObjectNode payload) {
            ClusterService cs = get(ClusterService.class);
            for (ControllerNode node : cs.getNodes()) {
                populateRow(tm.addRow(), node, cs);
            }
        }

        private void populateRow(TableModel.Row row, ControllerNode node,
                                 ClusterService cs) {
            NodeId id = node.id();
            DateTime lastUpdated = cs.getLastUpdated(id);
            ControllerNode.State state = cs.getState(id);
            String iconId = state.isActive() ? ICON_ID_ONLINE : ICON_ID_OFFLINE;
            String startedId = state.isReady() ? ICON_ID_ONLINE : ICON_ID_OFFLINE;

            row.cell(ID, id)
                .cell(IP, node.ip())
                .cell(TCP_PORT, node.tcpPort())
                .cell(STATE_IID, iconId)
                .cell(STARTED_IID, startedId)
                .cell(UPDATED, lastUpdated);
        }
    }

    private final class DetailRequestHandler extends RequestHandler {

        public DetailRequestHandler() {
            super(CLUSTER_DETAILS_REQ);
        }

        private List<Device> populateDevices(ControllerNode node) {
            DeviceService ds = get(DeviceService.class);
            MastershipService ms = get(MastershipService.class);
            return copyOf(ds.getDevices()).stream()
                    .filter(d -> ms.getMasterFor(d.id()).equals(node.id()))
                    .collect(Collectors.toList());
        }

        private String deviceProtocol(Device device) {
            String protocol = device.annotations().value(PROTOCOL);
            return protocol != null ? protocol : "";
        }

        private ObjectNode deviceData(Device d) {
            ObjectNode device = objectNode();

            device.put(URI, d.id().toString());
            device.put(TYPE, d.type().toString());
            device.put(CHASSIS_ID, d.chassisId().toString());
            device.put(MFR, d.manufacturer());
            device.put(HW, d.hwVersion());
            device.put(SW, d.swVersion());
            device.put(PROTOCOL, deviceProtocol(d));
            device.put(SERIAL, d.serialNumber());

            return device;
        }

        @Override
        public void process(ObjectNode payload) {

            String id = string(payload, ID);
            ClusterService cs = get(ClusterService.class);
            ControllerNode node = cs.getNode(new NodeId(id));

            ObjectNode data = objectNode();
            ArrayNode devices = arrayNode();
            List<Device> deviceList = populateDevices(node);

            data.put(ID, node.id().toString());
            data.put(IP, node.ip().toString());

            for (Device d : deviceList) {
                devices.add(deviceData(d));
            }

            data.set(DEVICES, devices);

            //TODO put more detail info to data

            ObjectNode rootNode = objectNode();
            rootNode.set(DETAILS, data);
            sendMessage(CLUSTER_DETAILS_RESP, rootNode);
        }
    }
}
