/*
 * 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 org.onosproject.ui.table.cell.IntComparator;

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.setComparator(PRIORITY, IntComparator.INSTANCE);

            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);
            }

        }
    }
}
