package com.airlock.iam.common.infrastructure.i18n;

import com.airlock.iam.common.infrastructure.json.ResourceBundleToJson;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.elog.api.LogTypes;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.servlet.ServletContext;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;

public class ServletContextBasedPropertiesLoader implements I18nJsonLoader {
   private static final Pattern JSON = Pattern.compile("(\\.json)$");
   private static final ELogger LOG = ELoggerFactory.getLogger(ServletContextBasedPropertiesLoader.class);
   private final ServletContext servletContext;
   private final ResourceBundleToJson bundleToJson = new ResourceBundleToJson();

   @SuppressFBWarnings({"NP_LOAD_OF_KNOWN_NULL_VALUE", "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
   @Override
   public Map<String, Object> loadJson(String pathToJsonResource) {
      String pathToPropertyResource = JSON.matcher(pathToJsonResource).replaceFirst(".properties");
      Map<String, String> result = new HashMap<>();

      try (InputStream resource = this.servletContext.getResourceAsStream(pathToPropertyResource)) {
         if (resource != null) {
            this.loadProperties(result, resource);
         }
      } catch (IOException e) {
         LOG.error(LogTypes.SERVER_INFO_SYS, "Failed to load Properties resource at " + pathToPropertyResource, e);
      }

      return this.bundleToJson.toJsonObject(result);
   }

   private void loadProperties(Map<String, String> result, InputStream resource) throws IOException {
      try (InputStreamReader reader = new InputStreamReader(resource, StandardCharsets.UTF_8)) {
         Properties properties = new Properties();
         properties.load(reader);

         for (String name : properties.stringPropertyNames()) {
            result.put(name, properties.getProperty(name));
         }
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   public ServletContextBasedPropertiesLoader(ServletContext servletContext) {
      this.servletContext = servletContext;
   }
}
