package org.apache.commons.jcs3.auxiliary.disk.indexed;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.jcs3.auxiliary.MockCacheEventLogger;
import org.apache.commons.jcs3.auxiliary.disk.DiskTestObject;
import org.apache.commons.jcs3.engine.CacheElement;
import org.apache.commons.jcs3.engine.ElementAttributes;
import org.apache.commons.jcs3.engine.behavior.ICacheElement;
import org.apache.commons.jcs3.engine.behavior.IElementAttributes;
import org.apache.commons.jcs3.engine.control.group.GroupAttrName;
import org.apache.commons.jcs3.engine.control.group.GroupId;
import org.apache.commons.jcs3.utils.timing.SleepUtil;

import junit.framework.TestCase;

/**
 * Tests for common functionality.
 * <p>
 *
 * @author Aaron Smuts
 */
public abstract class IndexDiskCacheUnitTestAbstract extends TestCase
{
    public abstract IndexedDiskCacheAttributes getCacheAttributes();

    /**
     * Simply verify that we can put items in the disk cache and retrieve them.
     *
     * @throws IOException
     */
    public void testSimplePutAndGet() throws IOException
    {
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testSimplePutAndGet");
        cattr.setMaxKeySize(1000);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, String> disk = new IndexedDiskCache<>(cattr);

        disk.processRemoveAll();

        final int cnt = 999;
        for (int i = 0; i < cnt; i++)
        {
            final IElementAttributes eAttr = new ElementAttributes();
            eAttr.setIsSpool(true);
            final ICacheElement<String, String> element = new CacheElement<>("testSimplePutAndGet", "key:" + i, "data:" + i);
            element.setElementAttributes(eAttr);
            disk.processUpdate(element);
        }

        for (int i = 0; i < cnt; i++)
        {
            final ICacheElement<String, String> element = disk.processGet("key:" + i);
            assertNotNull("Should have received an element.", element);
            assertEquals("Element is wrong.", "data:" + i, element.getVal());
        }

        // Test that getMultiple returns all the expected values
        final Set<String> keys = new HashSet<>();
        for (int i = 0; i < cnt; i++)
        {
            keys.add("key:" + i);
        }

        final Map<String, ICacheElement<String, String>> elements = disk.getMultiple(keys);
        for (int i = 0; i < cnt; i++)
        {
            final ICacheElement<String, String> element = elements.get("key:" + i);
            assertNotNull("element " + i + ":key is missing", element);
            assertEquals("value key:" + i, "data:" + i, element.getVal());
        }
        // System.out.println( disk.getStats() );
    }

    /**
     * Add some items to the disk cache and then remove them one by one.
     *
     * @throws IOException
     */
    public void testRemoveItems() throws IOException
    {
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testRemoveItems");
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, String> disk = new IndexedDiskCache<>(cattr);

        disk.processRemoveAll();

        final int cnt = 25;
        for (int i = 0; i < cnt; i++)
        {
            final IElementAttributes eAttr = new ElementAttributes();
            eAttr.setIsSpool(true);
            final ICacheElement<String, String> element = new CacheElement<>("testRemoveItems", "key:" + i, "data:" + i);
            element.setElementAttributes(eAttr);
            disk.processUpdate(element);
        }

        // remove each
        for (int i = 0; i < cnt; i++)
        {
            disk.remove("key:" + i);
            final ICacheElement<String, String> element = disk.processGet("key:" + i);
            assertNull("Should not have received an element.", element);
        }
    }

    /**
     * Verify that we don't override the largest item.
     * <p>
     *
     * @throws IOException
     */

    /**
     * Verify that the overlap check returns true when there are no overlaps.
     */
    public void testCheckForDedOverlaps_noOverlap()
    {
        // SETUP
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testCheckForDedOverlaps_noOverlap");
        cattr.setDiskPath("target/test-sandbox/UnitTest");
        final IndexedDiskCache<String, String> disk = new IndexedDiskCache<>(cattr);

        final int numDescriptors = 5;
        int pos = 0;
        final IndexedDiskElementDescriptor[] sortedDescriptors = new IndexedDiskElementDescriptor[numDescriptors];
        for (int i = 0; i < numDescriptors; i++)
        {
            final IndexedDiskElementDescriptor descriptor = new IndexedDiskElementDescriptor(pos, i * 2);
            pos = pos + (i * 2) + IndexedDisk.HEADER_SIZE_BYTES;
            sortedDescriptors[i] = descriptor;
        }

        // DO WORK
        final boolean result = disk.checkForDedOverlaps(sortedDescriptors);

        // VERIFY
        assertTrue("There should be no overlap. it should be ok", result);
    }

    /**
     * Verify that the overlap check returns false when there are overlaps.
     */
    public void testCheckForDedOverlaps_overlaps()
    {
        // SETUP
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testCheckForDedOverlaps_overlaps");
        cattr.setDiskPath("target/test-sandbox/UnitTest");
        final IndexedDiskCache<String, String> disk = new IndexedDiskCache<>(cattr);

        final int numDescriptors = 5;
        int pos = 0;
        final IndexedDiskElementDescriptor[] sortedDescriptors = new IndexedDiskElementDescriptor[numDescriptors];
        for (int i = 0; i < numDescriptors; i++)
        {
            final IndexedDiskElementDescriptor descriptor = new IndexedDiskElementDescriptor(pos, i * 2);
            // don't add the header + IndexedDisk.RECORD_HEADER;
            pos = pos + (i * 2);
            sortedDescriptors[i] = descriptor;
        }

        // DO WORK
        final boolean result = disk.checkForDedOverlaps(sortedDescriptors);

        // VERIFY
        assertFalse("There should be overlaps. it should be not ok", result);
    }

    /**
     * Verify that the file size is as expected.
     * <p>
     *
     * @throws IOException
     * @throws InterruptedException
     */
    public void testFileSize() throws IOException, InterruptedException
    {
        // SETUP
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testFileSize");
        cattr.setDiskPath("target/test-sandbox/UnitTest");
        final IndexedDiskCache<Integer, DiskTestObject> disk = new IndexedDiskCache<>(cattr);

        final int numberToInsert = 20;
        final int bytes = 24;
        final ICacheElement<Integer, DiskTestObject>[] elements = DiskTestObjectUtil.createCacheElementsWithTestObjects(numberToInsert,
            bytes, cattr.getCacheName());

        for (int i = 0; i < elements.length; i++)
        {
            disk.processUpdate(elements[i]);
        }

        Thread.yield();
        Thread.sleep(100);
        Thread.yield();

        final long expectedSize = DiskTestObjectUtil.totalSize(elements, numberToInsert);
        final long resultSize = disk.getDataFileSize();

        // System.out.println( "testFileSize stats " + disk.getStats() );

        assertEquals("Wrong file size", expectedSize, resultSize);
    }

    /**
     * Verify that items are added to the recycle bin on removal.
     * <p>
     *
     * @throws IOException
     * @throws InterruptedException
     */
    public void testRecyleBinSize() throws IOException, InterruptedException
    {
        // SETUP
        final int numberToInsert = 20;

        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testRecyleBinSize");
        cattr.setDiskPath("target/test-sandbox/UnitTest");
        cattr.setOptimizeAtRemoveCount(numberToInsert);
        cattr.setMaxKeySize(numberToInsert * 2);
        cattr.setMaxPurgatorySize(numberToInsert);
        final IndexedDiskCache<Integer, DiskTestObject> disk = new IndexedDiskCache<>(cattr);

        final int bytes = 1;
        final ICacheElement<Integer, DiskTestObject>[] elements = DiskTestObjectUtil.createCacheElementsWithTestObjects(numberToInsert,
            bytes, cattr.getCacheName());

        for (int i = 0; i < elements.length; i++)
        {
            disk.processUpdate(elements[i]);
        }

        Thread.yield();
        Thread.sleep(100);
        Thread.yield();

        // remove half
        final int numberToRemove = elements.length / 2;
        for (int i = 0; i < numberToRemove; i++)
        {
            disk.processRemove(elements[i].getKey());
        }

        // verify that the recycle bin has the correct amount.
        assertEquals("The recycle bin should have the number removed.", numberToRemove, disk.getRecyleBinSize());
    }

    /**
     * Verify that items of the same size use recycle bin spots. Setup the recycle bin by removing
     * some items. Add some of the same size. Verify that the recycle count is the number added.
     * <p>
     *
     * @throws IOException
     * @throws InterruptedException
     */
    public void testRecyleBinUsage() throws IOException, InterruptedException
    {
        // SETUP
        final int numberToInsert = 20;

        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testRecyleBinUsage");
        cattr.setDiskPath("target/test-sandbox/UnitTest");
        cattr.setOptimizeAtRemoveCount(numberToInsert);
        cattr.setMaxKeySize(numberToInsert * 2);
        cattr.setMaxPurgatorySize(numberToInsert);
        final IndexedDiskCache<Integer, DiskTestObject> disk = new IndexedDiskCache<>(cattr);

        // we will reuse these
        final int bytes = 1;
        final ICacheElement<Integer, DiskTestObject>[] elements = DiskTestObjectUtil.createCacheElementsWithTestObjects(numberToInsert,
            bytes, cattr.getCacheName());

        // Add some to the disk
        for (int i = 0; i < elements.length; i++)
        {
            disk.processUpdate(elements[i]);
        }

        Thread.yield();
        Thread.sleep(100);
        Thread.yield();

        // remove half of those added
        final int numberToRemove = elements.length / 2;
        for (int i = 0; i < numberToRemove; i++)
        {
            disk.processRemove(elements[i].getKey());
        }

        // verify that the recycle bin has the correct amount.
        assertEquals("The recycle bin should have the number removed.", numberToRemove, disk.getRecyleBinSize());

        // add half as many as we removed. These should all use spots in the recycle bin.
        final int numberToAdd = numberToRemove / 2;
        for (int i = 0; i < numberToAdd; i++)
        {
            disk.processUpdate(elements[i]);
        }

        // verify that we used the correct number of spots
        assertEquals("The recycle bin should have the number removed." + disk.getStats(), numberToAdd, disk.getRecyleCount());
    }

    /**
     * Verify that the data size is as expected after a remove and after a put that should use the
     * spots.
     * <p>
     *
     * @throws IOException
     * @throws InterruptedException
     */
    public void testBytesFreeSize() throws IOException, InterruptedException
    {
        // SETUP
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testBytesFreeSize");
        cattr.setDiskPath("target/test-sandbox/UnitTest");
        final IndexedDiskCache<Integer, DiskTestObject> disk = new IndexedDiskCache<>(cattr);

        final int numberToInsert = 20;
        final int bytes = 24;
        final ICacheElement<Integer, DiskTestObject>[] elements = DiskTestObjectUtil.createCacheElementsWithTestObjects(numberToInsert,
            bytes, cattr.getCacheName());

        for (int i = 0; i < elements.length; i++)
        {
            disk.processUpdate(elements[i]);
        }

        Thread.yield();
        Thread.sleep(100);
        Thread.yield();

        // remove half of those added
        final int numberToRemove = elements.length / 2;
        for (int i = 0; i < numberToRemove; i++)
        {
            disk.processRemove(elements[i].getKey());
        }

        final long expectedSize = DiskTestObjectUtil.totalSize(elements, numberToRemove);
        final long resultSize = disk.getBytesFree();

        // System.out.println( "testBytesFreeSize stats " + disk.getStats() );

        assertEquals("Wrong bytes free size" + disk.getStats(), expectedSize, resultSize);

        // add half as many as we removed. These should all use spots in the recycle bin.
        final int numberToAdd = numberToRemove / 2;
        for (int i = 0; i < numberToAdd; i++)
        {
            disk.processUpdate(elements[i]);
        }

        final long expectedSize2 = DiskTestObjectUtil.totalSize(elements, numberToAdd);
        final long resultSize2 = disk.getBytesFree();
        assertEquals("Wrong bytes free size" + disk.getStats(), expectedSize2, resultSize2);
    }

    /**
     * Add some items to the disk cache and then remove them one by one.
     * <p>
     *
     * @throws IOException
     */
    public void testRemove_PartialKey() throws IOException
    {
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testRemove_PartialKey");
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, String> disk = new IndexedDiskCache<>(cattr);

        disk.processRemoveAll();

        final int cnt = 25;
        for (int i = 0; i < cnt; i++)
        {
            final IElementAttributes eAttr = new ElementAttributes();
            eAttr.setIsSpool(true);
            final ICacheElement<String, String> element = new CacheElement<>("testRemove_PartialKey", i + ":key", "data:"
                + i);
            element.setElementAttributes(eAttr);
            disk.processUpdate(element);
        }

        // verif each
        for (int i = 0; i < cnt; i++)
        {
            final ICacheElement<String, String> element = disk.processGet(i + ":key");
            assertNotNull("Shoulds have received an element.", element);
        }

        // remove each
        for (int i = 0; i < cnt; i++)
        {
            disk.remove(i + ":");
            final ICacheElement<String, String> element = disk.processGet(i + ":key");
            assertNull("Should not have received an element.", element);
        }
        // https://issues.apache.org/jira/browse/JCS-67
        assertEquals("Recylenbin should not have more elements than we removed. Check for JCS-67", cnt, disk.getRecyleBinSize());
    }

    /**
     * Verify that group members are removed if we call remove with a group.
     *
     * @throws IOException
     */
    public void testRemove_Group() throws IOException
    {
        // SETUP
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testRemove_Group");
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<GroupAttrName<String>, String> disk = new IndexedDiskCache<>(cattr);

        disk.processRemoveAll();

        final String cacheName = "testRemove_Group_Region";
        final String groupName = "testRemove_Group";

        final int cnt = 25;
        for (int i = 0; i < cnt; i++)
        {
            final GroupAttrName<String> groupAttrName = getGroupAttrName(cacheName, groupName, i + ":key");
            final CacheElement<GroupAttrName<String>, String> element = new CacheElement<>(cacheName,
                groupAttrName, "data:" + i);

            final IElementAttributes eAttr = new ElementAttributes();
            eAttr.setIsSpool(true);
            element.setElementAttributes(eAttr);

            disk.processUpdate(element);
        }

        // verify each
        for (int i = 0; i < cnt; i++)
        {
            final GroupAttrName<String> groupAttrName = getGroupAttrName(cacheName, groupName, i + ":key");
            final ICacheElement<GroupAttrName<String>, String> element = disk.processGet(groupAttrName);
            assertNotNull("Should have received an element.", element);
        }

        // DO WORK
        // remove the group
        disk.remove(getGroupAttrName(cacheName, groupName, null));

        for (int i = 0; i < cnt; i++)
        {
            final GroupAttrName<String> groupAttrName = getGroupAttrName(cacheName, groupName, i + ":key");
            final ICacheElement<GroupAttrName<String>, String> element = disk.processGet(groupAttrName);

            // VERIFY
            assertNull("Should not have received an element.", element);
        }

    }

    /**
     * Internal method used for group functionality.
     * <p>
     *
     * @param cacheName
     * @param group
     * @param name
     * @return GroupAttrName
     */
    private GroupAttrName<String> getGroupAttrName(final String cacheName, final String group, final String name)
    {
        final GroupId gid = new GroupId(cacheName, group);
        return new GroupAttrName<>(gid, name);
    }

    /**
     * Verify event log calls.
     * <p>
     *
     * @throws Exception
     */
    public void testUpdate_EventLogging_simple() throws Exception
    {
        // SETUP
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testUpdate_EventLogging_simple");
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTestCEL");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);
        diskCache.processRemoveAll();

        final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
        diskCache.setCacheEventLogger(cacheEventLogger);

        final ICacheElement<String, String> item = new CacheElement<>("region", "key", "value");

        // DO WORK
        diskCache.update(item);

        SleepUtil.sleepAtLeast(200);

        // VERIFY
        assertEquals("Start should have been called.", 1, cacheEventLogger.startICacheEventCalls);
        assertEquals("End should have been called.", 1, cacheEventLogger.endICacheEventCalls);
    }

    /**
     * Verify event log calls.
     * <p>
     *
     * @throws Exception
     */
    public void testGet_EventLogging_simple() throws Exception
    {
        // SETUP
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testGet_EventLogging_simple");
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTestCEL");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);
        diskCache.processRemoveAll();

        final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
        diskCache.setCacheEventLogger(cacheEventLogger);

        // DO WORK
        diskCache.get("key");

        // VERIFY
        assertEquals("Start should have been called.", 1, cacheEventLogger.startICacheEventCalls);
        assertEquals("End should have been called.", 1, cacheEventLogger.endICacheEventCalls);
    }

    /**
     * Verify event log calls.
     * <p>
     *
     * @throws Exception
     */
    public void testGetMultiple_EventLogging_simple() throws Exception
    {
        // SETUP
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testGetMultiple_EventLogging_simple");
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTestCEL");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);
        diskCache.processRemoveAll();

        final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
        diskCache.setCacheEventLogger(cacheEventLogger);

        final Set<String> keys = new HashSet<>();
        keys.add("junk");

        // DO WORK
        diskCache.getMultiple(keys);

        // VERIFY
        // 1 for get multiple and 1 for get.
        assertEquals("Start should have been called.", 2, cacheEventLogger.startICacheEventCalls);
        assertEquals("End should have been called.", 2, cacheEventLogger.endICacheEventCalls);
    }

    /**
     * Verify event log calls.
     * <p>
     *
     * @throws Exception
     */
    public void testRemove_EventLogging_simple() throws Exception
    {
        // SETUP
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testRemoveAll_EventLogging_simple");
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTestCEL");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);
        diskCache.processRemoveAll();

        final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
        diskCache.setCacheEventLogger(cacheEventLogger);

        // DO WORK
        diskCache.remove("key");

        // VERIFY
        assertEquals("Start should have been called.", 1, cacheEventLogger.startICacheEventCalls);
        assertEquals("End should have been called.", 1, cacheEventLogger.endICacheEventCalls);
    }

    /**
     * Verify event log calls.
     * <p>
     *
     * @throws Exception
     */
    public void testRemoveAll_EventLogging_simple() throws Exception
    {
        // SETUP
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName("testRemoveAll_EventLogging_simple");
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTestCEL");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);
        diskCache.processRemoveAll();

        final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
        diskCache.setCacheEventLogger(cacheEventLogger);

        // DO WORK
        diskCache.remove("key");

        // VERIFY
        assertEquals("Start should have been called.", 1, cacheEventLogger.startICacheEventCalls);
        assertEquals("End should have been called.", 1, cacheEventLogger.endICacheEventCalls);
    }

    /**
     * Test the basic get matching.
     * <p>
     *
     * @throws Exception
     */
    public void testPutGetMatching_SmallWait() throws Exception
    {
        // SETUP
        final int items = 200;

        final String cacheName = "testPutGetMatching_SmallWait";
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName(cacheName);
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);

        // DO WORK
        for (int i = 0; i <= items; i++)
        {
            diskCache.update(new CacheElement<>(cacheName, i + ":key", cacheName + " data " + i));
        }
        Thread.sleep(500);

        final Map<String, ICacheElement<String, String>> matchingResults = diskCache.getMatching("1.8.+");

        // VERIFY
        assertEquals("Wrong number returned", 10, matchingResults.size());
        // System.out.println( "matchingResults.keySet() " + matchingResults.keySet() );
        // System.out.println( "\nAFTER TEST \n" + diskCache.getStats() );
    }

    /**
     * Test the basic get matching. With no wait this will all come from purgatory.
     * <p>
     *
     * @throws Exception
     */
    public void testPutGetMatching_NoWait() throws Exception
    {
        // SETUP
        final int items = 200;

        final String cacheName = "testPutGetMatching_NoWait";
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName(cacheName);
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);

        // DO WORK
        for (int i = 0; i <= items; i++)
        {
            diskCache.update(new CacheElement<>(cacheName, i + ":key", cacheName + " data " + i));
        }

        final Map<String, ICacheElement<String, String>> matchingResults = diskCache.getMatching("1.8.+");

        // VERIFY
        assertEquals("Wrong number returned", 10, matchingResults.size());
        // System.out.println( "matchingResults.keySet() " + matchingResults.keySet() );
        // System.out.println( "\nAFTER TEST \n" + diskCache.getStats() );
    }

    /**
     * Verify that the block disk cache can handle utf encoded strings.
     * <p>
     *
     * @throws Exception
     */
    public void testUTF8String() throws Exception
    {
        String string = "IÒtÎrn‚tiÙn‡lizÊti¯n";
        final StringBuilder sb = new StringBuilder();
        sb.append(string);
        for (int i = 0; i < 4; i++)
        {
            sb.append(sb.toString()); // big string
        }
        string = sb.toString();

        // System.out.println( "The string contains " + string.length() + " characters" );

        final String cacheName = "testUTF8String";

        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName(cacheName);
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);

        // DO WORK
        diskCache.update(new CacheElement<>(cacheName, "x", string));

        // VERIFY
        assertNotNull(diskCache.get("x"));
        Thread.sleep(1000);
        final ICacheElement<String, String> afterElement = diskCache.get("x");
        assertNotNull(afterElement);
        // System.out.println( "afterElement = " + afterElement );
        final String after = afterElement.getVal();

        assertNotNull(after);
        assertEquals("wrong string after retrieval", string, after);
    }

    /**
     * Verify that the block disk cache can handle utf encoded strings.
     * <p>
     *
     * @throws Exception
     */
    public void testUTF8ByteArray() throws Exception
    {
        String string = "IÒtÎrn‚tiÙn‡lizÊti¯n";
        final StringBuilder sb = new StringBuilder();
        sb.append(string);
        for (int i = 0; i < 4; i++)
        {
            sb.append(sb.toString()); // big string
        }
        string = sb.toString();
        // System.out.println( "The string contains " + string.length() + " characters" );
        final byte[] bytes = string.getBytes(StandardCharsets.UTF_8);

        final String cacheName = "testUTF8ByteArray";

        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName(cacheName);
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, byte[]> diskCache = new IndexedDiskCache<>(cattr);

        // DO WORK
        diskCache.update(new CacheElement<>(cacheName, "x", bytes));

        // VERIFY
        assertNotNull(diskCache.get("x"));
        Thread.sleep(1000);
        final ICacheElement<String, byte[]> afterElement = diskCache.get("x");
        assertNotNull(afterElement);
        // System.out.println( "afterElement = " + afterElement );
        final byte[] after = afterElement.getVal();

        assertNotNull(after);
        assertEquals("wrong bytes after retrieval", string, new String(after, StandardCharsets.UTF_8));
    }

    /**
     * Verify the item makes it to disk.
     * <p>
     *
     * @throws IOException
     */
    public void testProcessUpdate_Simple() throws IOException
    {
        // SETUP
        final String cacheName = "testProcessUpdate_Simple";
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName(cacheName);
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);

        final String key = "myKey";
        final String value = "myValue";
        final ICacheElement<String, String> ce = new CacheElement<>(cacheName, key, value);

        // DO WORK
        diskCache.processUpdate(ce);
        final ICacheElement<String, String> result = diskCache.processGet(key);

        // VERIFY
        assertNotNull("Should have a result", result);
        final long fileSize = diskCache.getDataFileSize();
        assertTrue("File should be greater than 0", fileSize > 0);
    }

    /**
     * Verify the item makes it to disk.
     * <p>
     *
     * @throws IOException
     */
    public void testProcessUpdate_SameKeySameSize() throws IOException
    {
        // SETUP
        final String cacheName = "testProcessUpdate_SameKeySameSize";
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName(cacheName);
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);

        final String key = "myKey";
        final String value = "myValue";
        final ICacheElement<String, String> ce1 = new CacheElement<>(cacheName, key, value);

        // DO WORK
        diskCache.processUpdate(ce1);
        final long fileSize1 = diskCache.getDataFileSize();

        // DO WORK
        final ICacheElement<String, String> ce2 = new CacheElement<>(cacheName, key, value);
        diskCache.processUpdate(ce2);
        final ICacheElement<String, String> result = diskCache.processGet(key);

        // VERIFY
        assertNotNull("Should have a result", result);
        final long fileSize2 = diskCache.getDataFileSize();
        assertEquals("File should be the same", fileSize1, fileSize2);
        final int binSize = diskCache.getRecyleBinSize();
        assertEquals("Should be nothing in the bin.", 0, binSize);
    }

    /**
     * Verify the item makes it to disk.
     * <p>
     *
     * @throws IOException
     */
    public void testProcessUpdate_SameKeySmallerSize() throws IOException
    {
        // SETUP
        final String cacheName = "testProcessUpdate_SameKeySmallerSize";
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName(cacheName);
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);

        final String key = "myKey";
        final String value = "myValue";
        final String value2 = "myValu";
        final ICacheElement<String, String> ce1 = new CacheElement<>(cacheName, key, value);

        // DO WORK
        diskCache.processUpdate(ce1);
        final long fileSize1 = diskCache.getDataFileSize();

        // DO WORK
        final ICacheElement<String, String> ce2 = new CacheElement<>(cacheName, key, value2);
        diskCache.processUpdate(ce2);
        final ICacheElement<String, String> result = diskCache.processGet(key);

        // VERIFY
        assertNotNull("Should have a result", result);
        final long fileSize2 = diskCache.getDataFileSize();
        assertEquals("File should be the same", fileSize1, fileSize2);
        final int binSize = diskCache.getRecyleBinSize();
        assertEquals("Should be nothing in the bin.", 0, binSize);
    }

    /**
     * Verify that the old slot gets in the recycle bin.
     * <p>
     *
     * @throws IOException
     */
    public void testProcessUpdate_SameKeyBiggerSize() throws IOException
    {
        // SETUP
        final String cacheName = "testProcessUpdate_SameKeyBiggerSize";
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName(cacheName);
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/IndexDiskCacheUnitTest");
        final IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);

        final String key = "myKey";
        final String value = "myValue";
        final String value2 = "myValue2";
        final ICacheElement<String, String> ce1 = new CacheElement<>(cacheName, key, value);

        // DO WORK
        diskCache.processUpdate(ce1);
        final long fileSize1 = diskCache.getDataFileSize();

        // DO WORK
        final ICacheElement<String, String> ce2 = new CacheElement<>(cacheName, key, value2);
        diskCache.processUpdate(ce2);
        final ICacheElement<String, String> result = diskCache.processGet(key);

        // VERIFY
        assertNotNull("Should have a result", result);
        final long fileSize2 = diskCache.getDataFileSize();
        assertTrue("File should be greater.", fileSize1 < fileSize2);
        final int binSize = diskCache.getRecyleBinSize();
        assertEquals("Should be one in the bin.", 1, binSize);
    }

    public void testLoadFromDisk() throws Exception
    {
        for (int i = 0; i < 15; i++)
        { // usually after 2 time it fails
            oneLoadFromDisk();
        }
    }

    public void oneLoadFromDisk() throws Exception
    {
        // initialize object to be stored
        String string = "IÒtÎrn‚tiÙn‡lizÊti¯n";
        final StringBuilder sb = new StringBuilder();
        sb.append(string);
        for (int i = 0; i < 4; i++)
        {
            sb.append(sb.toString()); // big string
        }
        string = sb.toString();

        // initialize cache
        final String cacheName = "testLoadFromDisk";
        final IndexedDiskCacheAttributes cattr = getCacheAttributes();
        cattr.setCacheName(cacheName);
        cattr.setMaxKeySize(100);
        cattr.setDiskPath("target/test-sandbox/BlockDiskCacheUnitTest");
        IndexedDiskCache<String, String> diskCache = new IndexedDiskCache<>(cattr);

        // DO WORK
        for (int i = 0; i < 50; i++)
        {
            diskCache.update(new CacheElement<>(cacheName, "x" + i, string));
        }
        // Thread.sleep(1000);
        // VERIFY
        diskCache.dispose();
        // Thread.sleep(1000);

        diskCache = new IndexedDiskCache<>(cattr);

        for (int i = 0; i < 50; i++)
        {
            final ICacheElement<String, String> afterElement = diskCache.get("x" + i);
            assertNotNull("Missing element from cache. Cache size: " + diskCache.getSize() + " element: x" + i, afterElement);
            assertEquals("wrong string after retrieval", string, afterElement.getVal());
        }
    }
}
