/*
 * Copyright 2016 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.base.Strings;
import com.google.common.collect.ImmutableSet;
import org.onosproject.net.DeviceId;
import org.onosproject.net.meter.Band;
import org.onosproject.net.meter.Meter;
import org.onosproject.net.meter.MeterService;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.table.CellFormatter;
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;

import java.util.Collection;

/**
 * Message handler for meter view related messages.
 */
public class MeterViewMessageHandler extends UiMessageHandler {

    private static final String METER_DATA_REQ = "meterDataRequest";
    private static final String METER_DATA_RESP = "meterDataResponse";
    private static final String METERS = "meters";

    private static final String ID = "id";
    private static final String APP_ID = "app_id";
    private static final String STATE = "state";
    private static final String PACKETS = "packets";
    private static final String BYTES = "bytes";
    private static final String BANDS = "bands";

    private static final String[] COL_IDS = {
            ID, APP_ID, STATE, PACKETS, BYTES, BANDS
    };

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

    // handler for meter table requests
    private final class MeterDataRequest extends TableRequestHandler {

        private MeterDataRequest() {
            super(METER_DATA_REQ, METER_DATA_RESP, METERS);
        }

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

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

        @Override
        protected void populateTable(TableModel tm, ObjectNode payload) {
            String uri = string(payload, "devId");
            if (!Strings.isNullOrEmpty(uri)) {
                DeviceId deviceId = DeviceId.deviceId(uri);
                MeterService ms = get(MeterService.class);
                for (Meter meter : ms.getMeters(deviceId)) {
                    populateRow(tm.addRow(), meter);
                }
            }
        }

        private void populateRow(TableModel.Row row, Meter m) {
            row.cell(ID, m.id().id())
                    .cell(APP_ID, m.appId().name())
                    .cell(STATE, m.state())
                    .cell(PACKETS, m.packetsSeen())
                    .cell(BYTES, m.bytesSeen())
                    .cell(BANDS, m.bands());
        }

        private final class BandFormatter implements CellFormatter {
            private static final String BREAK = "<br>";

            @Override
            public String format(Object value) {
                StringBuilder sb = new StringBuilder();
                Collection<Band> bands = (Collection<Band>) value;

                if (bands.isEmpty()) {
                    return "(No bands for this meter)";
                }

                // TODO: re-arrange band properties based on band type
                for (Band b : bands) {
                    sb.append("Bytes: ")
                            .append(b.bytes())
                            .append(" Packets: ")
                            .append(b.packets())
                            .append(" Type: ")
                            .append(b.type())
                            .append(BREAK);
                }

                return sb.toString();
            }
        }
    }
}
