/*
 * Copyright 2010 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.gwt.logging.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.ui.HasWidgets;

import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Configures client side logging using the query params and gwt.xml settings.
 */
public class LogConfiguration implements EntryPoint {
    
  private interface LogConfigurationImpl {
    void configureClientSideLogging();
    boolean loggingIsEnabled();
  }
  
  /** 
   * Implementation which does nothing and compiles out if logging is disabled.
   */
  private static class LogConfigurationImplNull
  implements LogConfigurationImpl {
    public void configureClientSideLogging() { }

    public boolean loggingIsEnabled() {
      return false;
    }
  }
  
  /** 
   * Implementation which is used when logging is enabled.
   */
  private static class LogConfigurationImplRegular
  implements LogConfigurationImpl {
    // Keep a reference to the root logger after we configure it because
    // if we don't, the JRE implementation of LogManager (which is used in
    // Dev Mode) will sometimes garbage collect it, since they only keep
    // weak references to the loggers that are created.
    private Logger root;

    public void configureClientSideLogging() {
      root = Logger.getLogger("");
      // In DevMode, this root logger will have a parent and we do not want this
      // root logger to pass messages to it's parent, so we set
      // useParentHandlers to false here.
      root.setUseParentHandlers(false);
      setLevels(root);
      setDefaultHandlers(root);
    }
  
    public boolean loggingIsEnabled() {
      return true;
    }
   
    private void addHandlerIfNotNull(Logger l, Handler h) {
      if (!(h instanceof NullLogHandler)) {
        l.addHandler(h);
      }
    }
    
    private Level parseLevel(String s) {
      if (s == null) {
        return null;
      }
      if (s.equals(Level.OFF.getName())) {
        return Level.OFF;
      } else if (s.equals(Level.SEVERE.getName())) {
        return Level.SEVERE;
      } else if (s.equals(Level.WARNING.getName())) {
        return Level.WARNING;
      } else if (s.equals(Level.INFO.getName())) {
        return Level.INFO;
      } else if (s.equals(Level.CONFIG.getName())) {
        return Level.CONFIG;
      } else if (s.equals(Level.FINE.getName())) {
        return Level.FINE;
      } else if (s.equals(Level.FINER.getName())) {
        return Level.FINER;
      } else if (s.equals(Level.FINEST.getName())) {
        return Level.FINEST;
      } else if (s.equals(Level.ALL.getName())) {
        return Level.ALL;
      }
      return null;
    }
  
    private void setDefaultHandlers(Logger l) {
      // Add the default handlers. If users want some of these disabled, they
      // will specify that in the gwt.xml file, which will replace the handler
      // with an instance of NullLogHandler, effectively disabling it.
      Handler console = GWT.create(ConsoleLogHandler.class);
      addHandlerIfNotNull(l, console);
      Handler dev = GWT.create(DevelopmentModeLogHandler.class);
      addHandlerIfNotNull(l, dev);
      Handler firebug = GWT.create(FirebugLogHandler.class);
      addHandlerIfNotNull(l, firebug);
      Handler system = GWT.create(SystemLogHandler.class);
      addHandlerIfNotNull(l, system);
      Handler remote = GWT.create(SimpleRemoteLogHandler.class);
      addHandlerIfNotNull(l, remote);
      HasWidgets loggingWidget = GWT.create(LoggingPopup.class);
      if (!(loggingWidget instanceof NullLoggingPopup)) {
        addHandlerIfNotNull(l, new HasWidgetsLogHandler(loggingWidget));
      }
    }

    private void setLevels(Logger l) {
      // try to pull the log level from the query param
      Level paramLevel = parseLevel(Location.getParameter("logLevel"));
      if (paramLevel != null) {
        l.setLevel(paramLevel);
      } else {
        // if it isn't there, then pull it from the gwt.xml file
        DefaultLevel defaultLevel = GWT.create(DefaultLevel.class);
        l.setLevel(defaultLevel.getLevel());
      }
    }
  }
  
  private static LogConfigurationImpl impl =
    GWT.create(LogConfigurationImplNull.class);
  
  public static boolean loggingIsEnabled() {
    return impl.loggingIsEnabled();
  }

  public void onModuleLoad() {
    impl.configureClientSideLogging();
    
    if (impl.loggingIsEnabled()) {
      if (GWT.getUncaughtExceptionHandler() == null) {
        final Logger log = Logger.getLogger(LogConfiguration.class.getName());
        GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
          public void onUncaughtException(Throwable e) {
            log.log(Level.SEVERE, e.getMessage(), e);
          }
        });
      }
    }
  }
}
