/*
 * Copyright 2015 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.test;

import com.google.common.collect.Maps;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mapdb.DB;
import org.mapdb.DBMaker;
import org.onosproject.persistence.impl.PersistentMap;
import org.onosproject.store.service.Serializer;

import java.nio.file.Paths;
import java.util.Map;
import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

/**
 * Test suite for Persistent Map.
 */
public class PersistentMapTest {

    private Map<Integer, Integer> map = null;
    private DB fakeDB = null;


    /**
     * Set up the database, create a map and a direct executor to handle it.
     *
     * @throws Exception if instantiation fails
     */
    @Before
    public void setUp() throws Exception {
        //Creates a db, a map within it and a basic integer serializer (async writing is off)
        fakeDB = DBMaker
                .newFileDB(Paths.get("../testDb").toFile())
                .asyncWriteEnable()
                .closeOnJvmShutdown()
                .make();
        map = new PersistentMap<Integer, Integer>(new Serializer() {
            @Override
            public <T> byte[] encode(T object) {
                if (object == null) {
                    return null;
                }
                int num = (Integer) object;
                byte[] result = new byte[4];

                result[0] = (byte) (num >> 24);
                result[1] = (byte) (num >> 16);
                result[2] = (byte) (num >> 8);
                result[3] = (byte) num;
                return result;
            }

            @Override
            public <T> T decode(byte[] bytes) {
                if (bytes == null) {
                    return null;
                }
                int num = 0x00000000;

                num = num | bytes[0] << 24;
                num = num | bytes[1] << 16;
                num = num | bytes[2] << 8;
                num = num | bytes[3];

                return (T) new java.lang.Integer(num);
            }
        }, fakeDB, "map");
    }

    /**
     * Clears and deletes the map, closes the datbase and deletes the file.
     *
     * @throws Exception if shutdown fails
     */
    @After
    public void tearDown() throws Exception {
        map.clear();
        fakeDB.delete("map:map");
        fakeDB.commit();
        fakeDB.close();
        //This is key to prevent artifacts persisting between tests.
        Paths.get("../testDB").toFile().delete();


    }

    @Test
    public void testRemove() throws Exception {
        //Checks removal and return values
        fillMap(10);
        assertEquals(10, map.size());
        for (int i = 0; i < 10; i++) {
            assertEquals("The previous value was wrong.", new Integer(i), map.remove(i));
            assertNull("The previous value was wrong.", map.remove(i));
            //(i+1) compensates for base zero.
            assertEquals("The size was wrong.", 10 - (i + 1), map.size());
        }
    }

    @Test
    public void testSize() throws Exception {
        //Checks size values throughout addition and removal
        for (int i = 0; i < 10; i++) {
            map.put(i, i);
            assertEquals("The map size is wrong.", i + 1, map.size());
        }
        for (int i = 0; i < 10; i++) {
            map.remove(i);
            assertEquals("The map size is wrong.", 9 - i, map.size());
        }
    }

    @Test
    public void testIsEmpty() throws Exception {
        //Checks empty condition
        //asserts that the map starts out empty
        assertTrue("Map should be empty", map.isEmpty());
        map.put(1, 1);
        assertFalse("Map shouldn't be empty.", map.isEmpty());
        map.remove(1);
        assertTrue("Map should be empty", map.isEmpty());
    }

    @Test
    public void testContains() throws Exception {
        //Checks both containsKey and containsValue be aware the implementations vary widely (value does not use mapDB
        //due to object '=='being an insufficient check)
        for (int i = 0; i < 10; i++) {
            assertFalse("Map should not contain the key", map.containsKey(i));
            assertFalse("Map should not contain the value", map.containsValue(i));
            map.put(i, i);
            assertTrue("Map should contain the key", map.containsKey(i));
            assertTrue("Map should contain the value", map.containsValue(i));
        }
    }

    @Test
    public void testGet() throws Exception {
        //Tests value retrieval and nonexistent key return values
        for (int i = 0; i < 10; i++) {
            map.put(i, i);
            for (int j = 0; j <= i; j++) {
                assertEquals("The value was wrong.", new Integer(j), map.get(j));
            }
        }
        assertNull("Null return value for nonexistent keys.", map.get(10));
    }

    @Test
    public void testPutAll() throws Exception {
        //Tests adding of an outside map
        Map<Integer, Integer> testMap = Maps.newHashMap();
        fillMap(10);
        map.putAll(testMap);
        for (int i = 0; i < 10; i++) {
            assertTrue("The map should contain the current 'i' value.", map.containsKey(i));
            assertTrue("The map should contain the current 'i' value.", map.containsValue(i));
        }
    }

    @Test
    public void testClear() throws Exception {
        //Tests clearing the map
        assertTrue("Map was initialized incorrectly, should be empty.", map.isEmpty());
        fillMap(10);
        assertFalse("Map should contain entries now.", map.isEmpty());
        map.clear();
        assertTrue("Map should have been cleared of entries.", map.isEmpty());

    }

    @Test
    public void testKeySet() throws Exception {
        //Tests key set generation
        fillMap(10);
        Set<Integer> keys = map.keySet();
        for (int i = 0; i < 10; i++) {
            assertTrue("The key set doesn't contain all keys 0-9", keys.contains(i));
        }
        assertEquals("The key set has an incorrect number of entries", 10, keys.size());
    }

    @Test
    public void testValues() throws Exception {
        //Tests value set generation
        fillMap(10);
        Set<Integer> values = (Set<Integer>) map.values();
        for (int i = 0; i < 10; i++) {
            assertTrue("The key set doesn't contain all keys 0-9", values.contains(i));
        }
        assertEquals("The key set has an incorrect number of entries", 10, values.size());
    }

    @Test
    public void testEntrySet() throws Exception {
        //Test entry set generation (violates abstraction by knowing the type of the returned entries)
        fillMap(10);
        Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
        for (int i = 0; i < 10; i++) {
            assertTrue("The key set doesn't contain all keys 0-9", entries.contains(Maps.immutableEntry(i, i)));
        }
        assertEquals("The key set has an incorrect number of entries", 10, entries.size());
    }

    @Test public void testPut() throws Exception {
        //Tests insertion behavior (particularly the returning of previous value)
        fillMap(10);
        for (int i = 0; i < 10; i++) {
            assertEquals("Put should return the previous value", new Integer(i), map.put(i, i + 1));
        }
        assertNull(map.put(11, 11));
    }

    /**
     * Populated the map with pairs of integers from (0, 0) up to (numEntries - 1, numEntries -1).
     * @param numEntries number of entries to add
     */
    private void fillMap(int numEntries) {
        for (int i = 0; i < numEntries; i++) {
            map.put(i, i);
        }
    }
}