/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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 android.net;

import android.net.ipmemorystore.Blob;
import android.net.ipmemorystore.NetworkAttributesParcelable;
import android.net.ipmemorystore.IOnBlobRetrievedListener;
import android.net.ipmemorystore.IOnL2KeyResponseListener;
import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
import android.net.ipmemorystore.IOnSameNetworkResponseListener;
import android.net.ipmemorystore.IOnStatusListener;

/** {@hide} */
oneway interface IIpMemoryStore {
    /**
     * Store network attributes for a given L2 key.
     * If L2Key is null, choose automatically from the attributes ; passing null is equivalent to
     * calling findL2Key with the attributes and storing in the returned value.
     *
     * @param l2Key The L2 key for the L2 network. Clients that don't know or care about the L2
     *              key and only care about grouping can pass a unique ID here like the ones
     *              generated by {@code java.util.UUID.randomUUID()}, but keep in mind the low
     *              relevance of such a network will lead to it being evicted soon if it's not
     *              refreshed. Use findL2Key to try and find a similar L2Key to these attributes.
     * @param attributes The attributes for this network.
     * @param listener A listener that will be invoked to inform of the completion of this call,
     *                 or null if the client is not interested in learning about success/failure.
     * @return (through the listener) The L2 key. This is useful if the L2 key was not specified.
     *         If the call failed, the L2 key will be null.
     */
    void storeNetworkAttributes(String l2Key, in NetworkAttributesParcelable attributes,
            IOnStatusListener listener);

    /**
     * Store a binary blob associated with an L2 key and a name.
     *
     * @param l2Key The L2 key for this network.
     * @param clientId The ID of the client.
     * @param name The name of this data.
     * @param data The data to store.
     * @param listener A listener to inform of the completion of this call, or null if the client
     *        is not interested in learning about success/failure.
     * @return (through the listener) A status to indicate success or failure.
     */
    void storeBlob(String l2Key, String clientId, String name, in Blob data,
            IOnStatusListener listener);

    /**
     * Returns the best L2 key associated with the attributes.
     *
     * This will find a record that would be in the same group as the passed attributes. This is
     * useful to choose the key for storing a sample or private data when the L2 key is not known.
     * If multiple records are group-close to these attributes, the closest match is returned.
     * If multiple records have the same closeness, the one with the smaller (unicode codepoint
     * order) L2 key is returned.
     * If no record matches these attributes, null is returned.
     *
     * @param attributes The attributes of the network to find.
     * @param listener The listener that will be invoked to return the answer.
     * @return (through the listener) The L2 key if one matched, or null.
     */
    void findL2Key(in NetworkAttributesParcelable attributes, IOnL2KeyResponseListener listener);

    /**
     * Returns whether, to the best of the store's ability to tell, the two specified L2 keys point
     * to the same L3 network. Group-closeness is used to determine this.
     *
     * @param l2Key1 The key for the first network.
     * @param l2Key2 The key for the second network.
     * @param listener The listener that will be invoked to return the answer.
     * @return (through the listener) A SameL3NetworkResponse containing the answer and confidence.
     */
    void isSameNetwork(String l2Key1, String l2Key2, IOnSameNetworkResponseListener listener);

    /**
     * Retrieve the network attributes for a key.
     * If no record is present for this key, this will return null attributes.
     *
     * @param l2Key The key of the network to query.
     * @param listener The listener that will be invoked to return the answer.
     * @return (through the listener) The network attributes and the L2 key associated with
     *         the query.
     */
    void retrieveNetworkAttributes(String l2Key, IOnNetworkAttributesRetrieved listener);

    /**
     * Retrieve previously stored private data.
     * If no data was stored for this L2 key and name this will return null.
     *
     * @param l2Key The L2 key.
     * @param clientId The id of the client that stored this data.
     * @param name The name of the data.
     * @param listener The listener that will be invoked to return the answer.
     * @return (through the listener) The private data (or null), with the L2 key
     *         and the name of the data associated with the query.
     */
    void retrieveBlob(String l2Key, String clientId, String name,
            IOnBlobRetrievedListener listener);
}
