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 (final ICacheElement<Integer, DiskTestObject> element : elements) {
            disk.processUpdate(element);
        }

        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 (final ICacheElement<Integer, DiskTestObject> element : elements) {
            disk.processUpdate(element);
        }

        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 (final ICacheElement<Integer, DiskTestObject> element : elements) {
            disk.processUpdate(element);
        }

        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 (final ICacheElement<Integer, DiskTestObject> element : elements) {
            disk.processUpdate(element);
        }

        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());
        }
    }
}
