// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.stash;
using fuchsia.mem;

/// Strings over 12 kb will be tossed. This number is chosen arbitrarily, if you
/// think it should be higher just ask.
const uint64 MAX_STRING_SIZE = 12000;
const uint64 MAX_KEY_SIZE = 256;

/// ValueType encodes a type for a field in the store
enum ValueType : uint8 {
    INT_VAL = 1;
    FLOAT_VAL = 2;
    BOOL_VAL = 3;
    STRING_VAL = 4;
    BYTES_VAL = 5;
};

/// ListItem is returned when a series of keys are being listed.
struct ListItem {
    string:MAX_KEY_SIZE key;
    ValueType type;
};

/// KeyValue is used when a series of keys are being read, or the default state
/// for the store is being set.
resource struct KeyValue {
    string:MAX_KEY_SIZE key;
    Value val;
};

/// Value holds a value for a given key.
resource union Value {
    1: int64 intval;
    2: float64 floatval;
    3: bool boolval;
    4: string:MAX_STRING_SIZE stringval;
    5: fuchsia.mem.Buffer bytesval;
};

// FlushError enumerates the various ways in which flushing the stash
// to disk may fail.
enum FlushError {
    // Failed to flush because the accessor is read-only.
    READ_ONLY = 1;

    // Failed to commit the requested operations.
    COMMIT_FAILED = 2;
};

/// The iterator returned when a series of keys are being listed. Returns an
/// empty vector when there are no more remaining ListItems.
protocol ListIterator {
    GetNext() -> (vector<ListItem>:MAX keys);
};

/// The iterator returned when a series of keys are being read. Returns an
/// empty vector when there are no more remaining KeyValues.
protocol GetIterator {
    GetNext() -> (vector<KeyValue>:MAX kvs);
};

/// The interface returned when a new accessor is created.
protocol StoreAccessor {
    /// Gets a single value from the store.
    GetValue(string:MAX_KEY_SIZE key) -> (Value? val);

    /// Sets a single value in the store. Overwrites existing values. Commit()
    /// must be called for this change to take effect.
    SetValue(string:MAX_KEY_SIZE key, Value val);

    /// Deletes a single value in the store. Does nothing if the value doesn't
    /// exist. Commit() must be called for this change to take effect.
    DeleteValue(string:MAX_KEY_SIZE key);

    /// Lists all keys under a given prefix.
    ListPrefix(string:MAX_KEY_SIZE prefix, request<ListIterator> it);

    /// Reads the values of all keys under a given prefix.
    GetPrefix(string:MAX_KEY_SIZE prefix, request<GetIterator> it);

    /// Deletes the all keys under a given prefix.
    DeletePrefix(string:MAX_KEY_SIZE prefix);

    /// Atomically causes all of the state modifications that happened in this
    /// accessor to take place.
    Commit();

    /// Atomically causes all of the state modifications that happened
    /// in this accessor to take place, returning only when those
    /// modifications were written to disk.
    /// This operation is equivalent to Commit.
    /// Returns a FlushError if this operations could not be committed.
    Flush() -> () error FlushError;
};

/// Interface used to interact with a given client's key/value store
[Discoverable]
protocol Store {
    /// Identify should be called at the beginning of a connection to identify
    /// which client service's store is to be accessed. In the future this will
    /// be deprecated in favor of component monikers, and each client will only
    /// be able to access its own store.
    Identify(string:MAX_KEY_SIZE name);

    /// Creates a accessor for interacting with the store. The resulting
    /// interface can be used to inspect and modify the state of the store.
    CreateAccessor(bool read_only, request<StoreAccessor> accessor_request);
};

/// A copy of |Store| in all but name. Behaves identically to |Store|.
/// See: fxbug.dev/48802
[Discoverable]
protocol Store2 {
    compose Store;
};

/// Interface used to interact with a given client's key/value store. The bytes
/// type is disabled in this store.
[Discoverable]
protocol SecureStore {
    compose Store;
};
