/*
 * 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.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_PAYLOAD = "intAppIntIntents";
    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_PAYLOAD);
        }

        @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<IntIntent.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 (IntIntent.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()));
            }
        }
    }
}
