/*
 * Copyright 2014 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.net.intent;

import org.onosproject.store.Store;

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

/**
 * Manages inventory of end-station intents; not intended for direct use.
 */
public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> {

    /**
     * Returns the number of intents in the store.
     *
     * @return the number of intents in the store
     */
    long getIntentCount();

    /**
     * Returns a collection of all intents in the store.
     *
     * @return iterable collection of all intents
     */
    Iterable<Intent> getIntents();

    /**
     * Returns the state of the specified intent.
     *
     * @param intentKey intent identification
     * @return current intent state
     */
    default IntentState getIntentState(Key intentKey) {
        return null;
    }

    /**
     * Returns the list of the installable events associated with the specified
     * original intent.
     *
     * @param intentKey original intent identifier
     * @return compiled installable intents
     */
    default List<Intent> getInstallableIntents(Key intentKey) {
        throw new UnsupportedOperationException("getInstallableIntents()");
    }

    /**
     * Writes an IntentData object to the store.
     *
     * @param newData new intent data to write
     */
    default void write(IntentData newData) {}

    /**
     * Writes a batch of IntentData objects to the store. A batch has no
     * semantics, this is simply a convenience API.
     *
     * @param updates collection of intent data objects to write
     */
    default void batchWrite(Iterable<IntentData> updates) {}

    /**
     * Returns the intent with the specified identifier.
     *
     * @param key key
     * @return intent or null if not found
     */
    default Intent getIntent(Key key) {
        // FIXME remove this default implementation when all stores have implemented it
        return null;
    }

    /**
     * Returns the intent data object associated with the specified key.
     *
     * @param key key to look up
     * @return intent data object
     */
    default IntentData getIntentData(Key key) { //FIXME remove when impl.
        return null;
    }

    /**
     * Adds a new operation, which should be persisted and delegated.
     *
     * @param intent operation
     */
    default void addPending(IntentData intent) {} //FIXME remove when impl.

    /**
     * Checks to see whether the calling instance is the master for processing
     * this intent, or more specifically, the key contained in this intent.
     *
     * @param intentKey intentKey to check
     * @return true if master; false, otherwise
     */
    //TODO better name
    default boolean isMaster(Key intentKey) { //FIXME remove default when impl.
        return true;
    }

    /**
     * Returns the intent requests pending processing.
     *
     * @return pending intents
     */
    // FIXME remove default
    default Iterable<Intent> getPending() {
        return Collections.emptyList();
    }
}
