/*
 * 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.inbandtelemetry.app.ui;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.onosproject.inbandtelemetry.api.IntIntent;
import org.onosproject.inbandtelemetry.api.IntIntentId;
import org.onosproject.net.behaviour.inbandtelemetry.IntMetadataType;
import org.onosproject.inbandtelemetry.api.IntService;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.TcpPortCriterion;
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * Message handler for installed INT intents table in the application UI.
 */
public class IntAppTableMessageHandler extends UiMessageHandler {
    private static final String INT_APP_INT_INTENT = "intAppIntIntent";
    private static final String INT_APP_INT_INTENT_DATA_REQUEST = INT_APP_INT_INTENT + "DataRequest";
    private static final String INT_APP_INT_INTENT_DATA_RESPONSE = INT_APP_INT_INTENT + "DataResponse";

    private static final String INT_APP_DEL_INT_INTENT_REQ = "intAppDelIntIntentRequest";

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

    private static final String ID = "id";
    private static final String SRC_ADDR = "srcAddr";
    private static final String DST_ADDR = "dstAddr";
    private static final String SRC_PORT = "srcPort";
    private static final String DST_PORT = "dstPort";
    private static final String PROTOCOL = "protocol";
    private static final String METADATA = "metadata";

    private static final String[] COLUMN_IDS = {ID, SRC_ADDR, DST_ADDR, SRC_PORT, DST_PORT, PROTOCOL, METADATA};

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

    protected IntService intService;

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

    // handler for table requests
    private final class IntAppIntIntentRequestHandler extends TableRequestHandler {

        private IntAppIntIntentRequestHandler() {
            super(INT_APP_INT_INTENT_DATA_REQUEST, INT_APP_INT_INTENT_DATA_RESPONSE, INT_APP_INT_INTENT);
        }

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

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

        private Map<IntIntentId, IntIntent> getAllIntIntents() {
            intService = get(IntService.class);
            return intService.getIntIntents();
        }

        @Override
        protected void populateTable(TableModel tm, ObjectNode payload) {
            Map<IntIntentId, IntIntent> intentMap = getAllIntIntents();
            intentMap.entrySet().forEach(entry ->
                                                 populateRow(tm.addRow(), entry.getKey(), entry.getValue()));
        }

        private void populateRow(TableModel.Row row, IntIntentId intentId, IntIntent intent) {
            IPCriterion ip4Src = (IPCriterion) intent.selector().getCriterion(Criterion.Type.IPV4_SRC);
            IPCriterion ip4Dst = (IPCriterion) intent.selector().getCriterion(Criterion.Type.IPV4_DST);
            TcpPortCriterion tcpSrcPort = (TcpPortCriterion) intent.selector().getCriterion(Criterion.Type.TCP_SRC);
            TcpPortCriterion tcpDstPort = (TcpPortCriterion) intent.selector().getCriterion(Criterion.Type.TCP_DST);
            UdpPortCriterion udpSrcPort = (UdpPortCriterion) intent.selector().getCriterion(Criterion.Type.UDP_SRC);
            UdpPortCriterion udpDstPort = (UdpPortCriterion) intent.selector().getCriterion(Criterion.Type.UDP_DST);
            Set<IntMetadataType> metadataTypes = intent.metadataTypes();
            row.cell(ID, intentId.toString())
                    .cell(SRC_ADDR, ip4Src == null ? "N/A" : ip4Src.ip().toString())
                    .cell(DST_ADDR, ip4Dst == null ? "N/A" : ip4Dst.ip().toString());
            if (tcpSrcPort != null || tcpDstPort != null) {
                row.cell(PROTOCOL, "TCP")
                        .cell(SRC_PORT, tcpSrcPort == null ? "N/A" : tcpSrcPort.tcpPort().toString())
                        .cell(DST_PORT, tcpDstPort == null ? "N/A" : tcpDstPort.tcpPort().toString());
            } else if (udpSrcPort != null || udpDstPort != null) {
                row.cell(PROTOCOL, "UDP")
                        .cell(SRC_PORT, udpSrcPort == null ? "N/A" : udpSrcPort.udpPort().toString())
                        .cell(DST_PORT, udpDstPort == null ? "N/A" : udpDstPort.udpPort().toString());
            } else {
                row.cell(PROTOCOL, "N/A")
                        .cell(SRC_PORT, "N/A")
                        .cell(DST_PORT, "N/A");
            }
            String metaStr = "";
            for (IntMetadataType metadataType : metadataTypes) {
                metaStr += metadataType.toString();
                metaStr += ", ";
            }
            row.cell(METADATA, metaStr);
        }
    }

    private final class IntAppDelIntIntentRequestHandler extends RequestHandler {

        private IntAppDelIntIntentRequestHandler() {
            super(INT_APP_DEL_INT_INTENT_REQ);
        }

        @Override
        public void process(ObjectNode payload) {
            intService = get(IntService.class);
            if (payload.get(ID) != null) {
                intService.removeIntIntent(IntIntentId.valueOf(payload.get(ID).asLong()));
            }
        }
    }
}
