// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.syncbase;

import io.v.syncbase.core.Permissions;
import io.v.syncbase.core.VError;
import io.v.v23.verror.VException;
import io.v.v23.vom.VomUtil;

/**
 * Represents an ordered set of key-value pairs.
 * To get a Collection handle, call {@code Database.collection}.
 */
public class Collection {
    private final io.v.syncbase.core.Collection mCoreCollection;
    private final DatabaseHandle mDatabaseHandle;
    private final Id mId;

    Collection(io.v.syncbase.core.Collection coreCollection, DatabaseHandle databaseHandle) {
        mCoreCollection = coreCollection;
        mDatabaseHandle = databaseHandle;
        mId = new Id(coreCollection.id());
    }

    void createIfMissing() {
        try {
            mCoreCollection.create(Syncbase.defaultCollectionPerms());
        } catch (VError vError) {
            if (vError.id.equals(VError.EXIST)) {
                return;
            }
            throw new RuntimeException("Failed to create collection", vError);
        }
    }

    /**
     * Returns the id of this collection.
     */
    public Id getId() {
        return mId;
    }

    /**
     * Shortcut for {@code Database.getSyncgroup(collection.getId())}, helpful for the common case
     * of one syncgroup per collection.
     * @throws IllegalArgumentException if this is collection on a batch database.
     */
    public Syncgroup getSyncgroup() {
        if (mDatabaseHandle instanceof BatchDatabase) {
            throw new IllegalArgumentException("Must not call getSyncgroup within batch");
        }
        return ((Database) mDatabaseHandle).getSyncgroup(getId());
    }

    // TODO(sadovsky): Add deleteRange API.
    // TODO(sadovsky): Maybe add scan API, if developers aren't satisfied with watch.

    // TODO(sadovsky): Revisit the get API:
    // - Is the Class<T> argument necessary?
    // - Should we take the target Object as an argument, to avoid allocations?
    // - What should it do if there is no value for the given key? (Currently, it returns null.)

    /**
     * Returns the value associated with {@code key}.
     */
    public <T> T get(String key, Class<T> cls) throws VError {
        try {
            return (T) VomUtil.decode(mCoreCollection.get(key), cls);
        } catch (VError vError) {
            if (vError.id.equals(VError.NO_EXIST)) {
                return null;
            }
            throw vError;
        } catch (VException e) {
            throw new VError(e);
        }
    }

    /**
     * Returns true if there is a value associated with {@code key}.
     */
    public boolean exists(String key) throws VError {
        return mCoreCollection.row(key).exists();
    }

    /**
     * Puts {@code value} for {@code key}, overwriting any existing value. Idempotent.
     */
    public <T> void put(String key, T value) throws VError {
        try {
            mCoreCollection.put(key, VomUtil.encode(value, value.getClass()));
        } catch (VException e) {
            throw new VError(e);
        }
    }

    /**
     * Deletes the value associated with {@code key}. Idempotent.
     */
    public void delete(String key) throws VError {
        mCoreCollection.delete(key);
    }

    /**
     * FOR ADVANCED USERS. Returns the {@code AccessList} for this collection. Users should
     * typically manipulate access lists via {@code collection.getSyncgroup()}.
     */
    public AccessList getAccessList() throws VError {
        return new AccessList(mCoreCollection.getPermissions());
    }

    /**
     * FOR ADVANCED USERS. Updates the {@code AccessList} for this collection. Users should
     * typically manipulate access lists via {@code collection.getSyncgroup()}.
     */
    public void updateAccessList(final AccessList delta) throws VError {
        final Id id = this.getId();
        Database.BatchOperation op = new Database.BatchOperation() {
            @Override
            public void run(BatchDatabase db) {
                io.v.syncbase.core.Collection coreCollection = db.getCollection(id).mCoreCollection;
                try {
                    Permissions newPermissions = AccessList.applyDelta(
                            coreCollection.getPermissions(), delta);
                    coreCollection.setPermissions(newPermissions);
                } catch (VError vError) {
                    throw new RuntimeException("updateAccessList failed", vError);
                }
            }
        };
        // Create a batch if we're not already in a batch.
        if (mDatabaseHandle instanceof BatchDatabase) {
            op.run((BatchDatabase) mDatabaseHandle);
        } else {
            ((Database) mDatabaseHandle).runInBatch(op, new Database.BatchOptions());
        }
    }
}
