/*
 * Copyright 2021 Danilo Reinert
 *
 * 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 io.reinert.requestor;

import java.util.HashMap;
import java.util.Map;

public class VolatileStore implements Store {

    private final Store persistentStore;
    private Map<String, Object> localDataMap;

    public static VolatileStore copy(VolatileStore volatileStore) {
        VolatileStore store = new VolatileStore(volatileStore.persistentStore);

        if (volatileStore.localDataMap != null) {
            store.localDataMap = new HashMap<String, Object>(volatileStore.localDataMap);
        }

        return store;
    }

    VolatileStore(Store store) {
        this.persistentStore = store;
    }

    @SuppressWarnings("unchecked")
    public <T> T get(String key) {
        T data = null;

        if (localDataMap != null) {
            data = (T) localDataMap.get(key);
        }

        if (data == null) {
            data = persistentStore.get(key);
        }

        return data;
    }

    public void put(String key, Object value, boolean sessionPersistent) {
        if (sessionPersistent) persistentStore.put(key, value, true);
        ensureDataMap().put(key, value);
    }

    public void put(String key, Object value) {
        this.put(key, value, false);
    }

    public boolean has(String key) {
        boolean has = persistentStore.has(key);

        if (has) return true;

        if (localDataMap == null) return false;

        return localDataMap.containsKey(key);
    }

    @SuppressWarnings("unchecked")
    public <T> T pop(String key) {
        T data = null;

        if (localDataMap != null) {
            data = (T) localDataMap.remove(key);
        }

        if (data == null) {
            data = persistentStore.get(key);
        }

        return data;
    }

    public void clear() {
        if (localDataMap != null) localDataMap.clear();
    }

    private Map<String, Object> ensureDataMap() {
        if (localDataMap == null) {
            localDataMap = new HashMap<String, Object>();
        }

        return localDataMap;
    }
}

@@ -1160,32 +1160,115 @@
 (Store store) %7B%0A
+        if (store == null) throw new NullPointerException(%22Store cannot be null%22);%0A
         this.per
@@ -1281,32 +1281,32 @@
 tStore = store;%0A
-
     %7D%0A%0A    @Supp
@@ -1494,32 +1494,59 @@
      if (data ==
+ null && persistentStore !=
  null) %7B%0A       
@@ -1726,16 +1726,43 @@
 rsistent
+ && persistentStore != null
 ) persis
@@ -1992,16 +1992,44 @@
 an has =
+  persistentStore != null &&
  persist
@@ -2363,32 +2363,32 @@
 ey);%0A        %7D%0A%0A
-
         if (data
@@ -2386,24 +2386,51 @@
  if (data ==
+ null && persistentStore !=
  null) %7B%0A   

Throw exception if store argument is null in VolatileStore