package com.example.myapexapp6;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.LinkedHashMap;
import java.util.Map;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.MapSerializer;

public class KryoSerDeTest {
  public static void main(String[] args) throws FileNotFoundException
  {
    TestClass clazz = new TestClass();
    clazz.getCache().put("ABC", "ABCDE");
    clazz.getCache().put("GHI", "GHIJK");

    com.esotericsoftware.minlog.Log.TRACE();
    Kryo kryo = new Kryo();
    kryo.register(LRUCache.class, new LRUCacheSerializer());
    Output output = new Output(new FileOutputStream("file.bin"));
    kryo.writeObject(output, clazz);
    output.close();
    Input input = new Input(new FileInputStream("file.bin"));
    TestClass clazz1 = kryo.readObject(input, TestClass.class);
    input.close();

    System.out.println(clazz1.getCache().getCapacity());
    System.out.println(clazz1.getCache().get("ABC"));
    System.out.println(clazz1.getCache().get("GHI"));
  }
}

class TestClass {

  LRUCache<String, String> cache;

  public TestClass() {
    cache = new LRUCache<String, String>(10, false);
  }

  public LRUCache<String, String> getCache() {
    return cache;
  }

  public void setCache(LRUCache<String, String> cache) {
    this.cache = cache;
  }
}

class LRUCache<K, V> extends LinkedHashMap<K, V>
{

  private static final long serialVersionUID = 1L;
  private int capacity = -1; // Maximum number of items in the cache.

  public int getCapacity() {
    return capacity;
  }

  public void setCapacity(int capacity) {
    this.capacity = capacity;
  }

  public LRUCache() {
    super();
  }

  public LRUCache(int capacity, boolean accessOrder) {
    super(capacity + 1, 1.0f, accessOrder); // Pass 'true' for accessOrder.
    setCapacity(capacity);
  }

  @Override
  public boolean removeEldestEntry(Map.Entry<K, V> entry) {
    if (capacity != -1) {
      return (size() > getCapacity());
    }
    return false;
  }
}

class LRUCacheSerializer extends MapSerializer
{
  public LRUCacheSerializer()
  {
  }

  @Override
  public void write(Kryo kryo, Output output, Map map)
  {
    super.write(kryo, output, map);
    output.writeInt(((LRUCache<?,?>)map).getCapacity());
  }

  @Override
  public Map read(Kryo kryo, Input input, Class<Map> type)
  {
    LRUCache<? ,?> map = (LRUCache<?,?>)super.read(kryo, input, type);
    map.setCapacity(input.readInt());
    return map;
  }
}

