/*
 * 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.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;
import static org.onosproject.net.MastershipRole.MASTER;


/**
 * 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() {
            DeviceService ds = get(DeviceService.class);
            return copyOf(ds.getDevices()).stream()
                    .filter(d -> ds.getRole(d.id()) == MASTER)
                    .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(long sid, 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();

            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);
        }
    }
}
