/*
 * Copyright 2016-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.drivermatrix;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.onosproject.net.driver.Behaviour;
import org.onosproject.net.driver.Driver;
import org.onosproject.net.driver.DriverService;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Message handler for driver matrix view related messages.
 */
public class DriverViewMessageHandler extends UiMessageHandler {

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

    private static final int ONE = 1;
    private static final String DRIVER_DATA_REQUEST = "driverDataRequest";
    private static final String DRIVER_DATA_RESPONSE = "driverDataResponse";

    private static final String DRIVERS = "drivers";
    private static final String BEHAVIOURS = "behaviours";
    private static final String MATRIX = "matrix";

    private static final Comparator<? super Class<? extends Behaviour>> BEHAVIOUR_BY_NAME =
            (o1, o2) -> o1.getSimpleName().compareTo(o2.getSimpleName());
    private static final Comparator<? super Driver> DRIVER_BY_NAME =
            (o1, o2) -> o1.name().compareTo(o2.name());


    @Override
    protected Collection<RequestHandler> createRequestHandlers() {
        return ImmutableSet.of(
                new DataRequestHandler()
                // TODO: for row selection, produce data for detail panel
//                new DetailRequestHandler()
        );
    }

    // handler for driver matrix requests
    private final class DataRequestHandler extends RequestHandler {

        private DataRequestHandler() {
            super(DRIVER_DATA_REQUEST);
        }

        @Override
        public void process(long sid, ObjectNode payload) {
            DriverService driverService = get(DriverService.class);

            List<Driver> drivers = new ArrayList<>(driverService.getDrivers());
            drivers = orderDrivers(drivers);

            // Produce a union of all behaviours (and order them)
            List<Class<? extends Behaviour>> behaviours = orderBehaviours(drivers);

            // Produce a JSON structure and send it
            sendMessage(DRIVER_DATA_RESPONSE, 0, driversJson(drivers, behaviours));
        }

        private List<Driver> orderDrivers(List<Driver> drivers) {
            // For now order by alphanumeric name of the driver
            drivers.sort(DRIVER_BY_NAME);
            return drivers;
        }

        private List<Class<? extends Behaviour>> orderBehaviours(List<Driver> drivers) {
            // first, produce a set-union of all behaviours from all drivers...
            Set<Class<? extends Behaviour>> allBehaviours = new HashSet<>();
            drivers.forEach(d -> allBehaviours.addAll(d.behaviours()));

            // for now, order by alphanumeric name of the abstract behaviour simple name
            List<Class<? extends Behaviour>> ordered = new ArrayList<>(allBehaviours);
            ordered.sort(BEHAVIOUR_BY_NAME);
            return ordered;
        }

        private ObjectNode driversJson(List<Driver> drivers,
                                       List<Class<? extends Behaviour>> behaviours) {
            ObjectNode root = objectNode();
            addBehaviours(root, behaviours);
            addDrivers(root, drivers);
            addMatrixCells(root, drivers);
            return root;
        }

        private void addBehaviours(ObjectNode root,
                                   List<Class<? extends Behaviour>> behaviours) {
            ArrayNode array = arrayNode();
            root.set(BEHAVIOURS, array);
            behaviours.forEach(b -> array.add(b.getSimpleName()));
        }

        private void addDrivers(ObjectNode root, List<Driver> drivers) {
            ArrayNode array = arrayNode();
            root.set(DRIVERS, array);
            drivers.forEach(d -> array.add(d.name()));
        }

        private Set<Driver> findLineage(Driver driver) {
            ImmutableSet.Builder<Driver> lineage = ImmutableSet.builder();
            lineage.add(driver);
            List<Driver> parents = driver.parents();
            if (parents != null) {
                parents.forEach(p -> lineage.addAll(findLineage(p)));
            }
            return lineage.build();
        }

        private void addMatrixCells(ObjectNode root, List<Driver> drivers) {
            ObjectNode matrix = objectNode();
            root.set(MATRIX, matrix);

            drivers.forEach(driver -> {
                ObjectNode dnode = objectNode();
                matrix.set(driver.name(), dnode);
                Set<Driver> lineage = findLineage(driver);
                lineage.forEach(d -> d.behaviours().forEach(b -> {
                    // TODO: can put a payload here, rather than a '1' marker
                    dnode.put(b.getSimpleName(), ONE);
                }));
            });
        }
    }
}
