content: package eu.the5zig.mod.config;
  
  import com.google.common.base.Charsets;
  import com.google.common.reflect.TypeToken;
  import com.google.gson.Gson;
  import com.google.gson.GsonBuilder;
  import eu.the5zig.mod.The5zigMod;
  import eu.the5zig.mod.server.Server;
  import org.apache.commons.io.FileUtils;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.List;
  
  public class Configuration<T> {
  
  	protected final File configFile;
  	protected final Class<T> configClass;
  	protected T configInstance;
  
  	public Configuration(File configFile, Class<T> configClass) {
  		this.configFile = configFile;
  		this.configClass = configClass;
  		setupWorkspace();
  	}
  
  	protected void setupWorkspace() {
  		try {
  			this.configInstance = loadConfig();
  			saveConfig();
  		} catch (Exception e) {
  			The5zigMod.logger.fatal("Could not load Configurations!", e);
  		}
  	}
  
  	public T createNewConfig(Class<T> configuration, File file) throws IOException {
  		if (file.exists()) {
  			if (!file.delete())
  				throw new IOException("Could not delete Config File at " + file.getPath());
  		}
  		if (!file.createNewFile())
  			throw new IOException("Could not create new Config File at " + file.getPath());
  
  		T instance;
  		try {
  			instance = configuration.newInstance();
  		} catch (Exception e) {
  			throw new RuntimeException("Could not create a new instance of " + configuration.getName(), e);
  		}
  
  		try {
  			saveConfig();
  		} catch (Exception e) {
  			e.printStackTrace();
  		}
  		The5zigMod.logger.info("Created new Configuration at " + file.getPath());
  		return instance;
  	}
  
  	public void saveConfig() {
  		The5zigMod.getAsyncExecutor().execute(new Runnable() {
  			@Override
  			public void run() {
  				try {
  					GsonBuilder gsonBuilder = new GsonBuilder();
  					registerTypeAdapters(gsonBuilder);
  					Gson gson = gsonBuilder.setPrettyPrinting().create();
  					String json = gson.toJson(configInstance);
  					FileUtils.writeStringToFile(configFile, json, Charsets.UTF_8);
  				} catch (IOException e) {
  					The5zigMod.logger.warn("Could not update Config File!", e);
  				}
  			}
  		});
  	}
  
  	protected void registerTypeAdapters(GsonBuilder gsonBuilder) {}
  
  	private T loadConfig() throws IOException {
  		if (!configFile.exists()) {
  			return createNewConfig(configClass, configFile);
  		}
  		String reader = FileUtils.readFileToString(configFile, Charsets.UTF_8);
  		GsonBuilder gsonBuilder = new GsonBuilder();
  		if (LastServer.class.isAssignableFrom(configClass))
  			gsonBuilder.registerTypeAdapter((new TypeToken<List<Server>>() {
  			}).getType(), new ServerAdapter());
  		try {
  			T t = gsonBuilder.create().fromJson(reader, configClass);
  			return t == null ? createNewConfig(configClass, configFile) : t;
  		} catch (Exception e) {
  			The5zigMod.logger.warn("Could not parse JSON at " + configFile.getPath(), e);
  			return createNewConfig(configClass, configFile);
  		}
  	}
  
  	public T getConfigInstance() {
  		return configInstance;
  	}
  }
  