/*
 * Copyright 2015-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.faultmanagement.alarms.gui;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import org.joda.time.DateTime;
import org.onosproject.incubator.net.faultmanagement.alarm.Alarm;
import org.onosproject.net.DeviceId;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.Set;

import static org.onosproject.incubator.net.faultmanagement.alarm.AlarmId.alarmId;

/**
 * Skeletal ONOS UI Table-View message handler.
 */
public class AlarmTableMessageHandler extends UiMessageHandler {

    private static final String ALARM_TABLE_DATA_REQ = "alarmTableDataRequest";
    private static final String ALARM_TABLE_DATA_RESP = "alarmTableDataResponse";
    private static final String ALARM_TABLES = "alarmTables";

    private static final String ALARM_TABLE_DETAIL_REQ = "alarmTableDetailsRequest";
    private static final String ALARM_TABLE_DETAIL_RESP = "alarmTableDetailsResponse";
    private static final String DETAILS = "details";

    private static final String ID = "id";
    private static final String DEVICE_ID_STR = "alarmDeviceId";
    private static final String DESCRIPTION = "alarmDesc";
    private static final String SOURCE = "alarmSource";
    private static final String TIME_RAISED = "alarmTimeRaised";
    private static final String TIME_UPDATED = "alarmTimeUpdated";
    private static final String TIME_CLEARED = "alarmTimeCleared";
    private static final String SEVERITY = "alarmSeverity";
    private static final String RESULT = "result";

    // TODO No need to show id column in ONOS-GUI

    // TODO Replace SEVERITY column by color-coding of row depending on severity
    // e.g. red=critical, green=cleared etc

    private static final String[] COLUMN_IDS = {
            ID, DEVICE_ID_STR, DESCRIPTION, SOURCE, TIME_RAISED, SEVERITY
    };

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

    @Override
    protected Collection<RequestHandler> createRequestHandlers() {
        return ImmutableSet.of(
                new AlarmTableDataRequestHandler(),
                new AlarmTableDetailRequestHandler()
        );
    }

    // handler for alarm table requests
    private final class AlarmTableDataRequestHandler extends TableRequestHandler {

        private static final String NO_ROWS_MESSAGE = "No alarms found";

        private AlarmTableDataRequestHandler() {
            super(ALARM_TABLE_DATA_REQ, ALARM_TABLE_DATA_RESP, ALARM_TABLES);
        }

        @Override
        protected String defaultColumnId() {
            return ID;
        }

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

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

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

        @Override
        protected void populateTable(TableModel tm, ObjectNode payload) {
            log.debug(" populateTable: tm = {}; payload = {}", tm, payload);
            String devId = string(payload, "devId");

            Set<Alarm> alarms = Strings.isNullOrEmpty(devId) ?
                    AlarmServiceUtil.lookUpAlarms() :
                    AlarmServiceUtil.lookUpAlarms(DeviceId.deviceId(devId));

            alarms.forEach((alarm) -> populateRow(tm.addRow(), alarm));
        }

        private void populateRow(TableModel.Row row, Alarm alarm) {
            log.debug("populateRow: row = {} alarm = {}", row, alarm);

            row.cell(ID, alarm.id())
                    .cell(DEVICE_ID_STR, alarm.deviceId())
                    .cell(DESCRIPTION, alarm.description())
                    .cell(SOURCE, alarm.source())
                    .cell(TIME_RAISED, new DateTime(alarm.timeRaised()))
                    .cell(SEVERITY, alarm.severity());
        }
    }

    // handler for alarm details requests
    private final class AlarmTableDetailRequestHandler extends RequestHandler {

        private AlarmTableDetailRequestHandler() {
            super(ALARM_TABLE_DETAIL_REQ);
        }

        @Override
        public void process(ObjectNode payload) {
            log.debug("payload = {}", payload);

            String id = string(payload, ID, "(none)");
            Alarm alarm = AlarmServiceUtil.lookupAlarm(alarmId(id));
            ObjectNode rootNode = objectNode();
            ObjectNode data = objectNode();
            rootNode.set(DETAILS, data);

            if (alarm == null) {
                rootNode.put(RESULT, "Item with id '" + id + "' not found");
                log.warn("attempted to get item detail for id '{}'", id);

            } else {
                rootNode.put(RESULT, "Found item with id '" + id + "'");

                data.put(ID, alarm.id().toString());
                data.put(DESCRIPTION, alarm.description());
                data.put(DEVICE_ID_STR, alarm.deviceId().toString());
                data.put(SOURCE, alarm.source().toString());
                long timeRaised = alarm.timeRaised();
                data.put(TIME_RAISED,
                         formatTime(timeRaised)
                );
                data.put(TIME_UPDATED, formatTime(alarm.timeUpdated()));
                data.put(TIME_CLEARED, formatTime(alarm.timeCleared()));
                data.put(SEVERITY, alarm.severity().toString());
            }
            log.debug("send = {}", rootNode);

            sendMessage(ALARM_TABLE_DETAIL_RESP, rootNode);
        }
    }

    private static String formatTime(Long msSinceStartOfEpoch) {
        if (msSinceStartOfEpoch == null) {
            return "-";
        }
        return new TimeFormatter().format(new DateTime(msSinceStartOfEpoch));
    }
}
