package com.sun.identity.shared.debug;

import com.sun.identity.shared.configuration.SystemPropertiesManager;
import com.sun.identity.shared.debug.impl.DebugProviderImpl;
import com.sun.identity.shared.locale.Locale;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

public class Debug {
   private static final String CONFIG_DEBUG_PROVIDER = "com.sun.identity.util.debug.provider";
   private static final IDebugProvider DEBUG_PROVIDER = createProvider();
   private static final Map<String, Debug> DEBUG_MAP = new HashMap<>();
   private IDebug debugServiceInstance;

   public static synchronized Debug getInstance(String debugName) {
      Debug debug = DEBUG_MAP.get(debugName);
      if (debug == null) {
         debug = new Debug(DEBUG_PROVIDER.getInstance(debugName));
         DEBUG_MAP.put(debugName, debug);
      }

      return debug;
   }

   private static synchronized IDebugProvider createProvider() {
      String providerName = SystemPropertiesManager.get("com.sun.identity.util.debug.provider");
      if (providerName != null && !providerName.trim().isEmpty()) {
         try {
            return (IDebugProvider)Class.forName(providerName).getDeclaredConstructor().newInstance();
         } catch (ClassNotFoundException | ClassCastException | IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException cnex) {
            ResourceBundle bundle = Locale.getInstallResourceBundle("amUtilMsgs");
            System.err.println(bundle.getString("com.iplanet.services.debug.invalidprovider"));
         }
      }

      return new DebugProviderImpl();
   }

   public String getName() {
      return this.debugServiceInstance.getName();
   }

   public boolean messageEnabled() {
      return this.debugServiceInstance.messageEnabled();
   }

   public boolean warningEnabled() {
      return this.debugServiceInstance.warningEnabled();
   }

   public int getState() {
      return this.debugServiceInstance.getState();
   }

   public void message(String msg) {
      this.debugServiceInstance.message(msg, null);
   }

   public void message(String msg, Throwable t) {
      this.debugServiceInstance.message(msg, t);
   }

   public void warning(String msg) {
      this.debugServiceInstance.warning(msg, null);
   }

   public void warning(String msg, Throwable t) {
      this.debugServiceInstance.warning(msg, t);
   }

   public void error(String msg) {
      this.debugServiceInstance.error(msg, null);
   }

   public void error(String msg, Throwable t) {
      this.debugServiceInstance.error(msg, t);
   }

   public void setDebug(int debugType) {
      this.debugServiceInstance.setDebug(debugType);
   }

   public void setDebug(String debugType) {
      this.debugServiceInstance.setDebug(debugType);
   }

   private void setDebugServiceInstance(IDebug debugServiceInstance) {
      this.debugServiceInstance = debugServiceInstance;
   }

   private Debug(IDebug debugServiceInstance) {
      this.setDebugServiceInstance(debugServiceInstance);
   }
}
