/*
 * Copyright 2015-present 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.ConnectPoint;
import org.onosproject.net.NetworkResource;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.intent.ConnectivityIntent;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.HostToHostIntent;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.LinkCollectionIntent;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.intent.PointToPointIntent;
import org.onosproject.net.intent.SinglePointToMultiPointIntent;
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 org.onosproject.ui.table.cell.AppIdFormatter;
import org.onosproject.ui.table.cell.EnumFormatter;

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

/**
 * Message handler for intent view related messages.
 */
public class IntentViewMessageHandler extends UiMessageHandler {

    private static final String INTENT_DATA_REQ = "intentDataRequest";
    private static final String INTENT_DATA_RESP = "intentDataResponse";
    private static final String INTENTS = "intents";

    private static final String APP_ID = "appId";
    private static final String KEY = "key";
    private static final String TYPE = "type";
    private static final String PRIORITY = "priority";
    private static final String STATE = "state";
    private static final String RESOURCES = "resources";
    private static final String DETAILS = "details";

    private static final String[] COL_IDS = {
            APP_ID, KEY, TYPE, PRIORITY, STATE, RESOURCES, DETAILS
    };

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

    // handler for intent table requests
    private final class IntentDataRequest extends TableRequestHandler {
        private static final String NO_ROWS_MESSAGE = "No intents found";

        private IntentDataRequest() {
            super(INTENT_DATA_REQ, INTENT_DATA_RESP, INTENTS);
        }

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

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

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

        @Override
        protected TableModel createTableModel() {
            TableModel tm = super.createTableModel();
            tm.setFormatter(APP_ID, AppIdFormatter.INSTANCE);
            tm.setFormatter(RESOURCES, new ResourcesFormatter());
            tm.setFormatter(DETAILS, new DetailsFormatter());
            tm.setFormatter(STATE, EnumFormatter.INSTANCE);
            return tm;
        }

        @Override
        protected void populateTable(TableModel tm, ObjectNode payload) {
            IntentService is = get(IntentService.class);
            for (Intent intent : is.getIntents()) {
                populateRow(tm.addRow(), intent, is);
            }
        }

        private void populateRow(TableModel.Row row, Intent intent, IntentService is) {
            row.cell(APP_ID, intent.appId())
                    .cell(KEY, intent.key())
                    .cell(TYPE, intent.getClass().getSimpleName())
                    .cell(PRIORITY, intent.priority())
                    .cell(STATE, is.getIntentState(intent.key()))
                    .cell(RESOURCES, intent)
                    .cell(DETAILS, intent);
        }

        private final class ResourcesFormatter implements CellFormatter {
            private static final String COMMA = ", ";

            @Override
            public String format(Object value) {
                Intent intent = (Intent) value;
                Collection<NetworkResource> resources = intent.resources();
                if (resources.isEmpty()) {
                    return "(No resources for this intent)";
                }
                StringBuilder sb = new StringBuilder("Resources: ");
                for (NetworkResource nr : resources) {
                    sb.append(nr).append(COMMA);
                }
                removeTrailingComma(sb);

                return sb.toString();
            }

            private StringBuilder removeTrailingComma(StringBuilder sb) {
                int pos = sb.lastIndexOf(COMMA);
                sb.delete(pos, sb.length());
                return sb;
            }
        }

        private final class DetailsFormatter implements CellFormatter {
            @Override
            public String format(Object value) {
                return formatDetails((Intent) value, new StringBuilder()).toString();
            }

            private StringBuilder formatDetails(Intent intent, StringBuilder sb) {
                if (intent instanceof ConnectivityIntent) {
                    buildConnectivityDetails((ConnectivityIntent) intent, sb);
                }

                if (intent instanceof HostToHostIntent) {
                    buildHostToHostDetails((HostToHostIntent) intent, sb);

                } else if (intent instanceof PointToPointIntent) {
                    buildPointToPointDetails((PointToPointIntent) intent, sb);

                } else if (intent instanceof MultiPointToSinglePointIntent) {
                    buildMPToSPDetails((MultiPointToSinglePointIntent) intent, sb);

                } else if (intent instanceof SinglePointToMultiPointIntent) {
                    buildSPToMPDetails((SinglePointToMultiPointIntent) intent, sb);

                } else if (intent instanceof PathIntent) {
                    buildPathDetails((PathIntent) intent, sb);

                } else if (intent instanceof LinkCollectionIntent) {
                    buildLinkConnectionDetails((LinkCollectionIntent) intent, sb);
                }

                if (sb.length() == 0) {
                    sb.append("(No details for this intent)");
                } else {
                    sb.insert(0, "Details: ");
                }
                return sb;
            }

            private void appendMultiPointsDetails(Set<ConnectPoint> points,
                                                  StringBuilder sb) {
                for (ConnectPoint point : points) {
                    sb.append(point.elementId())
                            .append('/')
                            .append(point.port())
                            .append(' ');
                }
            }

            private void buildConnectivityDetails(ConnectivityIntent intent,
                                                  StringBuilder sb) {
                Set<Criterion> criteria = intent.selector().criteria();
                List<Instruction> instructions = intent.treatment().allInstructions();
                List<Constraint> constraints = intent.constraints();

                if (!criteria.isEmpty()) {
                    sb.append("Selector: ").append(criteria);
                }
                if (!instructions.isEmpty()) {
                    sb.append("Treatment: ").append(instructions);
                }
                if (constraints != null && !constraints.isEmpty()) {
                    sb.append("Constraints: ").append(constraints);
                }
            }

            private void buildHostToHostDetails(HostToHostIntent intent,
                                                StringBuilder sb) {
                sb.append(" Host 1: ")
                        .append(intent.one())
                        .append(", Host 2: ")
                        .append(intent.two());
            }

            private void buildPointToPointDetails(PointToPointIntent intent,
                                                  StringBuilder sb) {
                ConnectPoint ingress = intent.ingressPoint();
                ConnectPoint egress = intent.egressPoint();
                sb.append(" Ingress: ")
                        .append(ingress.elementId())
                        .append('/')
                        .append(ingress.port())

                        .append(", Egress: ")
                        .append(egress.elementId())
                        .append('/')
                        .append(egress.port())
                        .append(' ');
            }

            private void buildMPToSPDetails(MultiPointToSinglePointIntent intent,
                                            StringBuilder sb) {
                ConnectPoint egress = intent.egressPoint();

                sb.append(" Ingress=");
                appendMultiPointsDetails(intent.ingressPoints(), sb);

                sb.append(", Egress=")
                        .append(egress.elementId())
                        .append('/')
                        .append(egress.port())
                        .append(' ');
            }

            private void buildSPToMPDetails(SinglePointToMultiPointIntent intent,
                                            StringBuilder sb) {
                ConnectPoint ingress = intent.ingressPoint();

                sb.append(" Ingress=")
                        .append(ingress.elementId())
                        .append('/')
                        .append(ingress.port())
                        .append(", Egress=");

                appendMultiPointsDetails(intent.egressPoints(), sb);
            }

            private void buildPathDetails(PathIntent intent, StringBuilder sb) {
                sb.append(" path=")
                        .append(intent.path().links())
                        .append(", cost=")
                        .append(intent.path().cost());
            }

            private void buildLinkConnectionDetails(LinkCollectionIntent intent,
                                                    StringBuilder sb) {
                sb.append(" links=")
                        .append(intent.links())
                        .append(", egress=");

                appendMultiPointsDetails(intent.egressPoints(), sb);
            }

        }
    }
}
