/*
 * Copyright 2016 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.store.primitives;

import com.google.common.base.Throwables;
import com.google.common.collect.Multiset;
import org.onosproject.store.service.AsyncConsistentMultimap;
import org.onosproject.store.service.ConsistentMapException;
import org.onosproject.store.service.ConsistentMultimap;
import org.onosproject.store.service.Synchronous;
import org.onosproject.store.service.Versioned;

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * Implementation of {@link ConsistentMultimap} providing synchronous access to
 * {@link AsyncConsistentMultimap}.
 */
public class DefaultConsistentMultimap<K, V>
        extends Synchronous<AsyncConsistentMultimap<K, V>>
        implements ConsistentMultimap<K, V> {

    private final AsyncConsistentMultimap<K, V> asyncMultimap;
    private final long operationTimeoutMillis;

    public DefaultConsistentMultimap(
            AsyncConsistentMultimap<K, V> asyncMultimap,
            long operationTimeoutMillis) {
        super(asyncMultimap);
        this.asyncMultimap = asyncMultimap;
        this.operationTimeoutMillis = operationTimeoutMillis;
    }

    @Override
    public int size() {
        return complete(asyncMultimap.size());
    }

    @Override
    public boolean isEmpty() {
        return complete(asyncMultimap.isEmpty());
    }

    @Override
    public boolean containsKey(K key) {
        return complete(asyncMultimap.containsKey(key));
    }

    @Override
    public boolean containsValue(V value) {
        return complete(asyncMultimap.containsValue(value));
    }

    @Override
    public boolean containsEntry(K key, V value) {
        return complete(asyncMultimap.containsEntry(key, value));
    }

    @Override
    public boolean put(K key, V value) {
        return complete(asyncMultimap.put(key, value));
    }

    @Override
    public boolean remove(K key, V value) {
        return complete(asyncMultimap.remove(key, value));
    }

    @Override
    public boolean removeAll(K key, Collection<? extends V> values) {
        return complete(asyncMultimap.removeAll(key, values));
    }

    @Override
    public Versioned<Collection<? extends V>> removeAll(K key) {
        return complete(asyncMultimap.removeAll(key));
    }

    @Override
    public boolean putAll(K key, Collection<? extends V> values) {
        return complete(asyncMultimap.putAll(key, values));
    }

    @Override
    public Versioned<Collection<? extends V>> replaceValues(
            K key, Collection<V> values) {
        return complete(asyncMultimap.replaceValues(key, values));
    }

    @Override
    public void clear() {
        complete(asyncMultimap.clear());
    }

    @Override
    public Versioned<Collection<? extends V>> get(K key) {
        return complete(asyncMultimap.get(key));
    }

    @Override
    public Set<K> keySet() {
        return complete(asyncMultimap.keySet());
    }

    @Override
    public Multiset<K> keys() {
        return complete(asyncMultimap.keys());
    }

    @Override
    public Multiset<V> values() {
        return complete(asyncMultimap.values());
    }

    @Override
    public Collection<Map.Entry<K, V>> entries() {
        return complete(asyncMultimap.entries());
    }

    @Override
    public Map<K, Collection<V>> asMap() {
        throw new UnsupportedOperationException("This operation is not yet " +
                                                        "supported.");
        //FIXME implement this when a new version of ConsistentMapBackedJavaMap is made for multimaps
    }

    private <T> T complete(CompletableFuture<T> future) {
        try {
            return future.get(operationTimeoutMillis, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new ConsistentMapException.Interrupted();
        } catch (TimeoutException e) {
            throw new ConsistentMapException.Timeout();
        } catch (ExecutionException e) {
            Throwables.propagateIfPossible(e.getCause());
            throw new ConsistentMapException(e.getCause());
        }
    }
}
