/*
 * 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.impl;

import com.google.gwt.core.client.GWT;

import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

/**
 * This class is used by the byte code rewriting which happens in DevMode only.
 * We rewrite all calls that create and access loggers by name to include a 
 * magic, thread specific prefix, which creates a separate tree of loggers for
 * each thread in DevMode. This works around the issue where DevMode root 
 * loggers are shared between threads and between client/server. These functions
 * will never be used in Production compiles.
 * 
 * TODO(unnurg): Move this class into gwt-dev
 * 
 * @see UseMirroredClasses
 */
public class DevModeLoggingFixes {
  private static Logger root = null;
  
  /**
   * Replaces all logRecord.getLoggerName() calls, removing a thread specific
   * prefix which is appended to all logger names in dev mode in order to
   * maintain a pseudo tree of loggers for each thread.
   */
  public static String getLoggerName(LogRecord record) {
    if (record.getLoggerName() != null) {
      return removeLoggerPrefix(record.getLoggerName());
    }
    return null;
  }
  
  /**
   * Replaces all logger.getName() calls, removing a thread specific prefix
   * which is appended to all logger names in dev mode in order to maintain
   * a pseudo tree of loggers for each thread.
   */
  public static String getName(Logger logger) {
    if (logger.getName() != null) {
      return removeLoggerPrefix(logger.getName());
    }
    return null;
  }
  
  /**
   * Replaces all Logger.getLogger(name) calls, adding a thread specific prefix
   * which is appended to all logger names in dev mode in order to maintain
   * a pseudo tree of loggers for each thread.
   */
  public static Logger loggerGetLogger(String name) {
    // If a library adds Loggers, but does not include the LogConfiguration
    // EntryPoint, then the separate root logger does not get created, and set
    // to ignore it's parent. In order to ensure that this happens, we do it
    // again here.
    if (root == null) {
      root = Logger.getLogger(getPrefixName());
      root.setUseParentHandlers(false);
    }
    return Logger.getLogger(addLoggerPrefix(name));
  }
  
  /**
   * Replaces all LogManager.getLogger(name) calls, adding a thread specific
   * prefix which is appended to all logger names in dev mode in order to
   * maintain a pseudo tree of loggers for each thread.
   */
  public static Logger logManagerGetLogger(LogManager manager, String name) {
    return manager.getLogger(addLoggerPrefix(name));
  }

  /**
   * Replaces all LogManager.getLoggerNames() calls, deleting the thread specific
   * prefix which is appended to all logger names in dev mode in order to
   * maintain a pseudo tree of loggers for each thread.  Also deletes all logger
   * names that do not start with the prefix since those belong to the server
   * and should not be returned in this function.
   */
  public static Enumeration<String> logManagerGetLoggerNames(LogManager manager) {
    Enumeration<String> loggerList = manager.getLoggerNames();
    List<String> newList = new ArrayList<String>();
    while (loggerList.hasMoreElements()) {
      String name = loggerList.nextElement();
      if (startsWithLoggerPrefix(name)) {
        newList.add(removeLoggerPrefix(name));
      }
    }
    return Collections.enumeration(newList);
  }
  
  private static String addLoggerPrefix(String name) {
    return getLoggerPrefix() + name;
  }
  
  private static String getLoggerPrefix() {
    return getPrefixName() + ".";
  }
  
  private static String getPrefixName() {
    return GWT.getUniqueThreadId();
  }
  
  private static String removeLoggerPrefix(String name) {
    return name.replaceFirst("^" + getLoggerPrefix(), "");
  }

  private static boolean startsWithLoggerPrefix(String name) {
    return name.startsWith(getLoggerPrefix());
  }
}
