package com.github.swissquote.carnotzet.core.util;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
import java.util.function.Function;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class FileSystemCache<T> {

	private final Path cachePath;
	private final Properties cache;
	private final Class<T> deserializationType;
	private final ObjectMapper jsonMapper;

	public FileSystemCache(Path cachePath, Class<T> deserializationType) {
		this.cachePath = cachePath;
		this.deserializationType = deserializationType;
		this.jsonMapper = new ObjectMapper();
		this.jsonMapper.registerModule(new JavaTimeModule());
		cache = new Properties();
		if (Files.notExists(cachePath)) {
			try {
				Files.createFile(cachePath);
			}
			catch (Exception e) {
				throw new RuntimeException(e.getMessage(), e);
			}
		}
	}

	public void load() throws IOException {
		try (FileInputStream cacheFileInputStream = new FileInputStream(this.cachePath.toFile())) {
			cache.load(cacheFileInputStream);
		}
	}

	public T computeIfAbsent(String key, Function<String, String> mappingFunction) throws IOException {
		try (FileInputStream cacheFileInputStream = new FileInputStream(this.cachePath.toFile()); Writer out = new OutputStreamWriter(
				new FileOutputStream(this.cachePath.toFile()), Charset.forName("UTF-8").newEncoder())) {
			this.cache.load(cacheFileInputStream);

			String value = (String) this.cache.get(key);
			if (value == null) {
				value = mappingFunction.apply(key);
				this.cache.put(key, value);
				this.cache.store(out, "image manifest cache");
			}

			T deserializedValue = this.jsonMapper.readValue(value, this.deserializationType);
			return deserializedValue;
		}

	}
}

@@ -1151,18 +1151,78 @@
 lic 
-void load(
+T computeIfAbsent(String key, Function%3CString, String%3E mappingFunction
 ) th
@@ -1337,16 +1337,21 @@
 )) %7B%0A%09%09%09
+this.
 cache.lo
@@ -1384,205 +1384,157 @@
 %09%09%7D%0A
-%09%7D%0A%0A%09public T computeIfAbsent(String key, Function%3CString, String%3E mappingFunction) throws IOException %7B%0A%09%09try (FileInputStream cacheFileInputStream = new FileInputStream(this.cachePath.toFile()); 
+%0A%09%09String value = (String) this.cache.get(key);%0A%09%09if (value == null) %7B%0A%09%09%09value = mappingFunction.apply(key);%0A%09%09%09this.cache.put(key, value);%0A%09%09%09try (
 Writ
@@ -1565,21 +1565,16 @@
 mWriter(
-%0A%09%09%09%09
 new File
@@ -1640,26 +1640,14 @@
 -8%22)
-.newEncoder(
 ))
-)
  %7B%0A
+%09
 %09%09%09t
@@ -1660,239 +1660,60 @@
 che.
-load(cacheFileInputStream);%0A%0A%09%09%09String value = (String) this.cache.get(key);%0A%09%09%09if (value == null) %7B%0A%09%09%09%09value = mappingFunction.apply(key);%0A%09%09%09%09this.cache.put(key, value);%0A%09%09%09%09this.cache.store(out, %22image manifest cache%22);
+store(out, %22Added value for key %22 + key);%0A%09%09%09%7D
 %0A%09%09
-%09
 %7D%0A%0A
-%09
 %09%09T 
@@ -1794,17 +1794,16 @@
 ype);%0A%09%09
-%09
 return d
@@ -1819,19 +1819,15 @@
 edValue;
-%0A%09%09%7D
 %0A%0A%09%7D%0A%7D%0A

Fix regression that was truncating the cache file at each write