/*
 * 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.onlab.onos.store.service.impl;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.notNull;

import java.util.Map;

import org.onlab.onos.store.serializers.StoreSerializer;
import org.onlab.onos.store.service.DatabaseAdminService;
import org.onlab.onos.store.service.DatabaseException;
import org.onlab.onos.store.service.DatabaseService;
import org.onlab.onos.store.service.VersionedValue;

import com.google.common.base.Function;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.FluentIterable;

/**
 * Map like interface wrapper around DatabaseService.
 *
 * @param <K> Key type of the map.
 *       The type must have toString(), which can uniquely identify the entry.
 * @param <V> Value type
 */
public class CMap<K, V> {

    @SuppressWarnings("unused")
    private final DatabaseAdminService dbAdminService;

    private final DatabaseService dbService;

    private final String tableName;
    private final StoreSerializer serializer;

    private final LoadingCache<K, String> keyCache;

    /**
     * Creates a CMap instance.
     * It will create the table if necessary.
     *
     * @param dbAdminService DatabaseAdminService to use for this instance
     * @param dbService DatabaseService to use for this instance
     * @param tableName table which this Map corresponds to
     * @param serializer Value serializer
     */
    public CMap(DatabaseAdminService dbAdminService,
                DatabaseService dbService,
                String tableName,
                StoreSerializer serializer) {

        this.dbAdminService = checkNotNull(dbAdminService);
        this.dbService = checkNotNull(dbService);
        this.tableName = checkNotNull(tableName);
        this.serializer = checkNotNull(serializer);

        boolean tableReady = false;
        do {
            try {
                if (!dbAdminService.listTables().contains(tableName)) {
                    dbAdminService.createTable(tableName);
                }
                tableReady = true;
            } catch (DatabaseException e) {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e1) {
                    throw new DatabaseException(e1);
                }
            }
        } while (!tableReady);

        keyCache = CacheBuilder.newBuilder()
                    .softValues()
                    .build(new CacheLoader<K, String>() {

                        @Override
                        public String load(K key) {
                            return key.toString();
                        }
                    });
    }

    protected String sK(K key) {
        return keyCache.getUnchecked(key);
    }

    protected byte[] sV(V val) {
        return serializer.encode(val);
    }

    protected V dV(byte[] valBytes) {
        return serializer.decode(valBytes);
    }

    /**
     * Puts an entry to the map, if not already present.
     *
     * @param key the key of the value to put if absent
     * @param value the value to be put if previous value does not exist
     * @return true if put was successful.
     */
    public boolean putIfAbsent(K key, V value) {
        return dbService.putIfAbsent(tableName, sK(key), sV(value));
    }

    /**
     * Removes an entry associated to specified key.
     *
     * @param key key of the value to remove
     * @return previous value in the map for the key
     */
    public V remove(K key) {
        VersionedValue removed = dbService.remove(tableName, sK(key));
        if (removed == null) {
            return null;
        }
        return dV(removed.value());
    }

    /**
     * Returns the size of the map.
     *
     * @return size of the map
     */
    public long size() {
        // TODO this is very inefficient
        return dbService.getAll(tableName).size();
    }

    /**
     * Returns all the values contained in the map.
     *
     * @return values containd in this map
     */
    public Iterable<V> values() {
        Map<String, VersionedValue> all = dbService.getAll(tableName);
        return FluentIterable.from(all.values())
                .transform(new Function<VersionedValue, V>() {

                    @Override
                    public V apply(VersionedValue input) {
                        if (input == null) {
                            return null;
                        }
                        return dV(input.value());
                    }
                })
                .filter(notNull());
    }

    /**
     * Gets the value in the map.
     *
     * @param key to get from the map
     * @return value associated with the key, null if not such entry
     */
    public V get(K key) {
        VersionedValue vv = dbService.get(tableName, sK(key));
        if (vv == null) {
            return null;
        }
        return dV(vv.value());
    }

    /**
     * Replaces the value in the map if the value matches the expected.
     *
     * @param key of the entry to replace
     * @param oldVal value expected to be in the map
     * @param newVal value to be replaced with
     * @return true if successfully replaced
     */
    public boolean replace(K key, V oldVal, V newVal) {
        return dbService.putIfValueMatches(tableName, sK(key), sV(oldVal), sV(newVal));
    }

    /**
     * Puts a value int the map.
     *
     * @param key key with which the specified value is to be associated
     * @param value value to be associated with the specified key
     * @return previous value or null if not such entry
     */
    public V put(K key, V value) {
        VersionedValue vv = dbService.put(tableName, sK(key), sV(value));
        if (vv == null) {
            return null;
        }
        return dV(vv.value());
    }
}