/*
 * 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.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.onosproject.net.packet.PacketProcessorEntry;
import org.onosproject.net.packet.PacketService;
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.NumberFormatter;

import java.util.Collection;

import static org.onosproject.net.packet.PacketProcessor.ADVISOR_MAX;
import static org.onosproject.net.packet.PacketProcessor.DIRECTOR_MAX;

/**
 * Message handler for packet processor view related messages.
 */
public class ProcessorViewMessageHandler extends UiMessageHandler {

    private static final String PROCESSOR_DATA_REQ = "processorDataRequest";
    private static final String PROCESSOR_DATA_RESP = "processorDataResponse";
    private static final String PROCESSORS = "processors";

    private static final String ID = "id";
    private static final String TYPE = "type";
    private static final String PRIORITY = "priority";
    private static final String PROCESSOR = "processor";
    private static final String PACKETS = "packets";
    private static final String AVG_MS = "avgMillis";

    private static final long NANOS_IN_MS = 1_000_000;

    private static final String[] COL_IDS = {
            ID, TYPE, PRIORITY, PROCESSOR, PACKETS, AVG_MS
    };

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

    // handler for link table requests
    private final class ProcessorDataRequest extends TableRequestHandler {
        private ProcessorDataRequest() {
            super(PROCESSOR_DATA_REQ, PROCESSOR_DATA_RESP, PROCESSORS);
        }

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

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

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

        @Override
        protected void populateTable(TableModel tm, ObjectNode payload) {
            PacketService ps = get(PacketService.class);
            ps.getProcessors().forEach(entry -> populateRow(tm.addRow(), entry));
        }

        private void populateRow(TableModel.Row row, PacketProcessorEntry entry) {
            row.cell(ID, entry.priority())
                    .cell(TYPE, processorType(entry.priority()))
                    .cell(PRIORITY, processorPriority(entry.priority()))
                    .cell(PROCESSOR, entry.processor().getClass().getName())
                    .cell(PACKETS, entry.invocations())
                    .cell(AVG_MS, entry.averageNanos() / NANOS_IN_MS);
        }

        private String processorType(int p) {
            return p > DIRECTOR_MAX ? "observer" :
                    p > ADVISOR_MAX ? "director" : "observer";
        }

        private int processorPriority(int p) {
            return p > DIRECTOR_MAX ? (p - DIRECTOR_MAX - 1) :
                    p > ADVISOR_MAX ? (p - ADVISOR_MAX - 1) : (p - 1);
        }

    }
}
