/*
 * Copyright 2015-present 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.persistence.impl;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.mapdb.DB;
import org.mapdb.Hasher;
import org.onosproject.store.service.Serializer;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

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


/**
 * A map implementation that stores and receives all data from a serialized internal map.
 */
public class PersistentMap<K, V> implements Map<K, V> {

    private final Serializer serializer;

    private final org.mapdb.DB database;

    private final Map<byte[], byte[]> items;

    private final String name;

    public PersistentMap(Serializer serializer, DB database, String name) {
        this.serializer = checkNotNull(serializer);
        this.database = checkNotNull(database);
        this.name = checkNotNull(name);

        items = database
                .createHashMap(name)
                .keySerializer(org.mapdb.Serializer.BYTE_ARRAY)
                .valueSerializer(org.mapdb.Serializer.BYTE_ARRAY)
                .hasher(Hasher.BYTE_ARRAY)
                .makeOrGet();
    }

    /**
     * Reads this set in deserialized form into the provided map.
     *
     * @param items the map to be populated
     */
    public void readInto(Map<K, V> items) {
        this.items.forEach((keyBytes, valueBytes) ->
                                   items.put(serializer.decode(keyBytes),
                                             serializer.decode(valueBytes)));
    }

    @Override
    public V remove(Object key) {
        checkNotNull(key, "Key can not be null.");
        V removed = get(key);
        items.remove(serializer.encode(key));
        return removed;
    }

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

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

    @Override
    public boolean containsKey(Object key) {
        checkNotNull(key, "Key cannot be null.");
        return items.containsKey(serializer.encode(key));
    }

    @Override
    public boolean containsValue(Object value) {
        checkNotNull(value, "Value cannot be null.");
        byte[] serialized = serializer.encode(value);
        for (byte[] compareValue : items.values()) {
            boolean same = true;
            if (compareValue == null) {
                same = false;
            } else if (compareValue.length != serialized.length) {
                same = false;
            } else {
                for (int i = 0; i < serialized.length; i++) {
                    if (serialized[i] != compareValue[i]) {
                        same = false;
                        break;
                    }
                }
            }
            if (same) {
                return true;
            }
        }
        return false;
    }

    @Override
    public V get(Object key) {
        checkNotNull(key, "Key cannot be null.");
        return serializer.decode(items.get(serializer.encode(key)));
    }

    @Override
    public V put(K key, V value) {
        checkNotNull(key, "Key cannot be null.");
        checkNotNull(value, "Value cannot be null.");
        byte[] prevVal = items.put(serializer.encode(key), serializer.encode(value));
        if (prevVal == null) {
            return null;
        }
        return serializer.decode(prevVal);
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        checkNotNull(m, "The passed in map cannot be null.");
        m.forEach((k, v) -> items.put(serializer.encode(k), serializer.encode(v)));
    }

    @Override
    public void clear() {
        items.clear();
    }

    @Override
    public Set<K> keySet() {
        Set<K> keys = Sets.newHashSet();
        items.keySet().forEach(k -> keys.add(serializer.decode(k)));
        return keys;
    }

    @Override
    public Collection<V> values() {
        Collection<V> values = Sets.newHashSet();
        items.values().forEach(v -> values.add(serializer.decode(v)));
        return values;
    }

    @Override
    public Set<Entry<K, V>> entrySet() {
        Set<Entry<K, V>> entries = Sets.newHashSet();
        items.entrySet().
                forEach(e -> entries.add(Maps.immutableEntry(serializer.decode(e.getKey()),
                                                             serializer.decode(e.getValue()))));
        return entries;
    }

    @Override
    public boolean equals(Object map) {
        //This is not threadsafe and on larger maps incurs a significant processing cost
        if (!(map instanceof Map)) {
            return false;
        }
        Map asMap = (Map) map;
        if (this.size() != asMap.size()) {
            return false;
        }
        for (Entry entry : this.entrySet()) {
            Object key = entry.getKey();
            if (!asMap.containsKey(key) || !asMap.get(key).equals(entry.getValue())) {
                return false;
            }
        }
        return true;
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }
}