/*
 * 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.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 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 RESOURCES = "resources";
    private static final String DETAILS = "details";

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

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

    // handler for intent table requests
    private final class IntentDataRequest extends TableRequestHandler {
        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 TableModel createTableModel() {
            TableModel tm = super.createTableModel();
            tm.setFormatter(APP_ID, AppIdFormatter.INSTANCE);
            tm.setFormatter(RESOURCES, new ResourcesFormatter());
            tm.setFormatter(DETAILS, new DetailsFormatter());
            return tm;
        }

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

        private void populateRow(TableModel.Row row, Intent intent) {
            row.cell(APP_ID, intent.appId())
                .cell(KEY, intent.key())
                .cell(TYPE, intent.getClass().getSimpleName())
                .cell(PRIORITY, intent.priority())
                .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);
            }

        }
    }
}
