package org.micord.utils;

import org.micord.exceptions.FileNotModifiedException;
import org.micord.models.Requests;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Maksim Tereshin
 */
@Component
public class ConfigLoader {

	private static final Logger LOGGER = Logger.getLogger(ConfigLoader.class.getName());
	private final Map<String, FileTime> lastModifiedTimes = new HashMap<>();

	@Value("${configDirectory}")
	private String configDirectory;

	public Optional<Requests> loadConfigIfModified(String methodName) throws FileNotModifiedException {
		String fileName = methodName + ".xml";
		if (configDirectory == null) {
			LOGGER.log(Level.SEVERE, "No configuration directory found for method: " + methodName);
			return Optional.empty();
		}

		try {
			File configFile = new File(configDirectory + File.separator + fileName);
			Path configFilePath = configFile.toPath();

			FileTime currentModifiedTime = Files.getLastModifiedTime(configFilePath);
			FileTime lastModifiedTime = lastModifiedTimes.getOrDefault(methodName, null);

			if (lastModifiedTime == null || currentModifiedTime.compareTo(lastModifiedTime) > 0) {
				lastModifiedTimes.put(methodName, currentModifiedTime);

				// Load the updated configuration
				JAXBContext jaxbContext = JAXBContext.newInstance(Requests.class);
				Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
				Requests loadedConfig = (Requests) unmarshaller.unmarshal(configFile);

				return Optional.of(loadedConfig);
			} else {
				throw new FileNotModifiedException("Configuration file for method " + methodName + " has not been modified.");
			}

		} catch (IOException e) {
			LOGGER.log(Level.SEVERE, "Failed to load configuration file: " + fileName, e);
			return Optional.empty();  // Return empty if there is an IO error
		} catch (JAXBException e) {
			LOGGER.log(Level.SEVERE, "Failed to unmarshal configuration file: " + fileName, e);
			return Optional.empty();  // Return empty if unmarshalling fails
		}
	}

}