/*
 * 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.topo;

import org.onosproject.net.intent.Intent;
import org.onosproject.ui.topo.NodeSelection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Encapsulates a selection of intents (paths) inferred from a selection
 * of devices and/or hosts from the topology view.
 */
public class IntentSelection {

    private static final int ALL = -1;

    protected static final Logger log =
            LoggerFactory.getLogger(IntentSelection.class);

    private final NodeSelection nodes;

    private final List<Intent> intents;
    private int index = ALL;

    /**
     * Creates an intent selection group, based on selected nodes.
     *
     * @param nodes node selection
     * @param filter intent filter
     */
    public IntentSelection(NodeSelection nodes, TopoIntentFilter filter) {
        this.nodes = nodes;
        intents = filter.findPathIntents(nodes.hosts(), nodes.devices());
        if (intents.size() == 1) {
            index = 0;  // pre-select a single intent
        }
    }

    /**
     * Creates an intent selection group, for a single intent.
     *
     * @param intent the intent
     */
    public IntentSelection(Intent intent) {
        nodes = null;
        intents = new ArrayList<>(1);
        intents.add(intent);
        index = 0;
    }

    /**
     * Returns true if no intents are selected.
     *
     * @return true if nothing selected
     */
    public boolean none() {
        return intents.isEmpty();
    }

    /**
     * Returns true if all intents in this select group are currently selected.
     * This is the initial state, so that all intents are shown on the
     * topology view with primary highlighting.
     *
     * @return true if all selected
     */
    public boolean all() {
        return index == ALL;
    }

    /**
     * Returns true if there is a single intent in this select group, or if
     * a specific intent has been marked (index != ALL).
     *
     * @return true if single intent marked
     */
    public boolean single() {
        return !all();
    }

    /**
     * Returns the number of intents in this selection group.
     *
     * @return number of intents
     */
    public int size() {
        return intents.size();
    }

    /**
     * Returns the index of the currently selected intent.
     *
     * @return the current index
     */
    public int index() {
        return index;
    }

    /**
     * The list of intents in this selection group.
     *
     * @return list of intents
     */
    public List<Intent> intents() {
        return Collections.unmodifiableList(intents);
    }

    /**
     * Marks and returns the next intent in this group. Note that the
     * selection wraps around to the beginning again, if necessary.
     *
     * @return the next intent in the group
     */
    public Intent next() {
        index += 1;
        if (index >= intents.size()) {
            index = 0;
        }
        return intents.get(index);
    }

    /**
     * Marks and returns the previous intent in this group. Note that the
     * selection wraps around to the end again, if necessary.
     *
     * @return the previous intent in the group
     */
    public Intent prev() {
        index -= 1;
        if (index < 0) {
            index = intents.size() - 1;
        }
        return intents.get(index);
    }

    /**
     * Returns the currently marked intent, or null if "all" intents
     * are marked.
     *
     * @return the currently marked intent
     */
    public Intent current() {
        return all() ? null : intents.get(index);
    }

    @Override
    public String toString() {
        return "IntentSelection{" +
                "nodes=" + nodes +
                ", #intents=" + intents.size() +
                ", index=" + index +
                '}';
    }

}
