package be.iminds.ilabt.jfed.log.cache;

import be.iminds.ilabt.jfed.call_log_output.SerializableApiCallDetails;
import be.iminds.ilabt.jfed.call_log_output.SerializableApiCallDetailsFactory;
import be.iminds.ilabt.jfed.log.ApiCallDetails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.util.HashMap;
import java.util.Map;

/**
 * User: twalcari
 * Date: 4/15/2014
 * Time: 15:56
 */
public class MemoryApiCallDetailsCache extends ApiCallDetailsCache {

    private static final Logger LOG = LoggerFactory.getLogger(MemoryApiCallDetailsCache.class);

    private final Map<ApiCallDetailsRef, byte[]> compressedApiCallDetails = new HashMap<>();
    private final SerializableApiCallDetailsFactory serializableApiCallDetailsFactory;

    @Inject
    public MemoryApiCallDetailsCache(SerializableApiCallDetailsFactory serializableApiCallDetailsFactory) {
        this.serializableApiCallDetailsFactory = serializableApiCallDetailsFactory;
    }

    @Override
    protected SerializableApiCallDetails getFullApiDetails(ApiCallDetailsRef ref) {
        return decompressFullApiDetails(compressedApiCallDetails.get(ref));
    }

    @Override
    public void clear() {
        compressedApiCallDetails.clear();
    }


    @Override
    public ApiCallDetailsRef registerApiCallDetails(ApiCallDetails apiCallDetails) {
        ApiCallDetailsRef ref = new ApiCallDetailsRef(apiCallDetails);

        if (!compressedApiCallDetails.containsKey(ref)) {
            compressedApiCallDetails.put(ref, compressFullApiDetails(
                    serializableApiCallDetailsFactory.createFromApiCallDetails(apiCallDetails)
            ));
        }

        return ref;
    }

    @Override
    public ApiCallDetailsRef registerApiCallDetails(SerializableApiCallDetails apiCallDetails) {
        //first create a copy of the received SerializableApiCallDetails
        SerializableApiCallDetails copy = new SerializableApiCallDetails(apiCallDetails);

        ApiCallDetailsRef ref = new ApiCallDetailsRef(copy);

        if (!compressedApiCallDetails.containsKey(ref)) {
            compressedApiCallDetails.put(ref, compressFullApiDetails(copy));
        }

        return ref;
    }

    @Override
    public SerializableApiCallDetails getApiCallDetails(ApiCallDetailsRef apiCallDetailsRef) {
        assert (compressedApiCallDetails.containsKey(apiCallDetailsRef));
        return super.getApiCallDetails(apiCallDetailsRef);
    }


}
