/*
 * Copyright 2007 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.
 */
#ifndef JNI_LINUX_TRACER_H_
#define JNI_LINUX_TRACER_H_

#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <jni.h>

// comment this out to remove almost all runtime overhead (with usual compiler
// support) from tracing.
#define ENABLE_TRACING

/*
 * Utility class for tracing.  This class is intended to be used as follows:
 * 
 * {
 *   Tracer tracer("method name");
 *   ... do work
 *   if (fail) {
 *      tracer.setFail("failure explanation");
 *      return;
 *   }
 *   if (fail2) {
 *      tracer.throwHostedModeException("failure explanation");
 *      return;
 *   }
 *   return;
 * }
 * 
 * The class automatically logs an enter message when it is created, as well
 * as leave/fail messages when it is destroyed.  Logging is performed to a
 * file or to a Java static member function on a class (or both) -- these
 * are configured by using static member functions setFile() and setJava().
 * 
 * This class knows about the Java class
 *   com.google.gwt.dev.shell.HostedModeException
 * and throws a new instance of that exception if requested.
 */
class Tracer {
public:
  enum LogLevel {
    LEVEL_ERROR = 0,
    LEVEL_WARNING,
    LEVEL_NOTICE,
    LEVEL_INFO,
    LEVEL_DEBUG,
    LEVEL_DEBUG_V1,
    LEVEL_DEBUG_V2,
  };
protected:
#ifdef ENABLE_TRACING
  // static variables that specify where logging is performed.  This are
  // set by calling setFile() and setJava().
  static FILE*     outfp;
  static JNIEnv*   jniEnv;
  static jclass    traceClass;
  static jmethodID traceMethod;
  static int       indentation;
  static LogLevel  logLevel;

  // method is set when the instance is created.
  const char*		method_;
  // fail_msg is set to indicate a failure has occurred.
  const char*		fail_msg_;
  // level of this trace object
  LogLevel  log_level_;
#endif
  
public:
  /*
   * Set the logging level.
   */
  static void setLevel(LogLevel level) {
#ifdef ENABLE_TRACING
    logLevel = level;
#endif
  }
  
protected:
  /*
   * Log a message (with supplied prefix) to the configured file.
   * Only called if a file was specified and successfully opened for writing.
   */
  static void logFile(const char* msg) {
#ifdef ENABLE_TRACING
    for (int i = 0; i < indentation; ++i) {
      putc(' ', outfp);
    }
    fputs(msg, outfp);
    putc('\n', outfp);
    fflush(outfp);
#else
    (void)msg; // avoid unused warning
#endif
  }

  /*
   * Log a message (with supplied prefix) to the configured Java class.
   * Only called if a file was specified and successfully accessed.
   * 
   * Call static void trace(String msg) on the configured class. 
   */
  static void logJava(const char* msg) {
#ifdef ENABLE_TRACING
    // TODO(jat): fixed buffer size
    char buf[512];
    for (int i = 0; (i < indentation) && (i < int(sizeof(buf))); ++i) {
      buf[i] = ' ';
    }
    strncpy(buf + indentation, msg, sizeof(buf) - indentation);
    buf[sizeof(buf) - 1] = 0; // ensure null termination
    jstring str = jniEnv->NewStringUTF(buf);
    jniEnv->CallStaticVoidMethod(traceClass, traceMethod, str);
#else
    (void)msg; // avoid unused warning
#endif
  }

  /*
   * Log a message to a file and/or class with the default logging level.
   * 
   * If the preprocessor symbol DISABLE_TRACING has been defined, this is
   * completely removed from the code path.
   */
  void logPrefix(const char* prefix) {
#ifdef ENABLE_TRACING
    logPrefix(prefix, log_level_);
#else
    (void)prefix; // avoid unused warning
#endif
  }
  
  /*
   * Log a message to a file and/or class.
   * 
   * If the preprocessor symbol DISABLE_TRACING has been defined, this is
   * completely removed from the code path.
   */
  void logPrefix(const char* prefix, LogLevel level) {
#ifdef ENABLE_TRACING
    if (level>logLevel) return;
    log("%-5.5s %s%s%s", prefix, method_, fail_msg_ ? ": " : "",
        fail_msg_ ? fail_msg_ : "");
#endif
  }
    
public:
  /*
   * Create an instance with the specified method name and no failure
   * message.  Log an ENTER message.
   */
  Tracer(const char* method, LogLevel log_level = LEVEL_ERROR)
#ifdef ENABLE_TRACING
      : method_(method), fail_msg_(0), log_level_(log_level) {
    log("ENTER %s", method);
    indentation++;
#else
  { (void)method; (void)log_level; // avoid unused warnings
#endif
  }

  /*
   * Create an instance with the specified method name and no failure
   * message.  Log an ENTER message and the this pointer.
   */
  Tracer(const char* method, const void* objThis,
      LogLevel log_level = LEVEL_ERROR)
#ifdef ENABLE_TRACING
      : method_(method), fail_msg_(0), log_level_(log_level) {
    log("ENTER %s(this=%08x)", method, unsigned(objThis));
    indentation++;
#else
  { (void)method; (void)objThis; (void)log_level; // avoid unused warnings
#endif
  }

  /*
   * Destroy the instance and log a fail or leave message.
   */
  ~Tracer() {
#ifdef ENABLE_TRACING
    --indentation;
    if(fail_msg_) {
      logPrefix("*FAIL", LEVEL_ERROR);
    } else {
      logPrefix("LEAVE");
    }
#endif
  }
  
  /*
   * Specify a filename to receive logging output.  Close any previously
   * opened file.  If a null filename is passed, disable logging to a
   * file.
   * 
   * filename - the file path to receive logging output.  This file is
   *     truncated if it already exists.
   * 
   * Returns false on failure.
   */
  static bool setFile(const char* filename) {
#ifdef ENABLE_TRACING
    if (outfp) {
      fclose(outfp);
      outfp = 0;
    }
    if (!filename) {
      return true;
    }
    outfp = fopen(filename, "w");
    if (!outfp) {
      return false;
    }
    fprintf(outfp, "== started logging ==\n");
    fflush(outfp);
#else
    (void)filename; // avoid unused warning
#endif
    return true;
  }
  
  /*
   * Specify a Java class to receive logging output.  The supplied class
   * must have a static void trace(String) member function which is called
   * for output.  Logging to a Java class is disabled if the supplied JNI
   * environment is null.
   * 
   * env - JNI environment
   * clazz - the Java class to receive logging output
   * 
   * Returns false on failure.
   */ 
  static bool setJava(JNIEnv* env, jclass clazz)
#ifdef ENABLE_TRACING  
  ;
#else
  // inline a null body if we aren't debugging; avoid unused warnings
  { (void)env; (void)clazz; return true; }
#endif
  
  /*
   * Set a failure message, overwriting any previously specified failure
   * message.  Passing a null string will remove any previous failure
   * notification.
   */
  void setFail(const char* fail_msg) {
#ifdef ENABLE_TRACING
    fail_msg_ = fail_msg;
#else
    (void)fail_msg; // avoid unused warning
#endif
  }
  
  /*
   * Throw a Java HostedModeException as well as set a failure message to
   * be logged.
   * 
   * env - JNI environment to throw exception into
   * fail_msg - failure message 
   */
  void throwHostedModeException(JNIEnv* env, const char* fail_msg);
  
  /*
   * Log an arbitrary message.
   */
  static void log(const char* format, ...) {
#ifdef ENABLE_TRACING
    va_list args;
    va_start(args, format);
    char msg[512]; // TODO(jat): fixed size buffer
    vsnprintf(msg, sizeof(msg), format, args);
    msg[sizeof(msg) - 1] = 0; // ensure null termination
    if(outfp) logFile(msg);
    if(jniEnv) logJava(msg);
    va_end(args);
#else
    (void)format; // avoid unused warning
#endif
  }
};

#endif /* JNI_LINUX_TRACER_H_ */
