/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.webrtc;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.EnumSet;

/** Java wrapper for WebRTC logging. */
public class Logging {
  static {
    try {
      System.loadLibrary("jingle_peerconnection_so");
    } catch (Throwable t) {
    }
  }

  // Keep in sync with webrtc/common_types.h:TraceLevel.
  public enum TraceLevel {
    TRACE_NONE(0x0000),
    TRACE_STATEINFO(0x0001),
    TRACE_WARNING(0x0002),
    TRACE_ERROR(0x0004),
    TRACE_CRITICAL(0x0008),
    TRACE_APICALL(0x0010),
    TRACE_DEFAULT(0x00ff),
    TRACE_MODULECALL(0x0020),
    TRACE_MEMORY(0x0100),
    TRACE_TIMER(0x0200),
    TRACE_STREAM(0x0400),
    TRACE_DEBUG(0x0800),
    TRACE_INFO(0x1000),
    TRACE_TERSEINFO(0x2000),
    TRACE_ALL(0xffff);

    public final int level;
    TraceLevel(int level) {
      this.level = level;
    }
  };

  // Keep in sync with webrtc/base/logging.h:LoggingSeverity.
  public enum Severity {
    LS_SENSITIVE, LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR,
  };

  public static void enableLogThreads() {
    nativeEnableLogThreads();
  }

  public static void enableLogTimeStamps() {
    nativeEnableLogTimeStamps();
  }

  // Enable tracing to |path| of messages of |levels| and |severity|.
  // On Android, use "logcat:" for |path| to send output there.
  public static void enableTracing(
      String path, EnumSet<TraceLevel> levels, Severity severity) {
    int nativeLevel = 0;
    for (TraceLevel level : levels) {
      nativeLevel |= level.level;
    }
    nativeEnableTracing(path, nativeLevel, severity.ordinal());
  }

  public static void log(Severity severity, String tag, String message) {
    try {
      nativeLog(severity.ordinal(), tag, message);
    } catch (Throwable t) {
    }
  }

  public static void d(String tag, String message) {
    log(Severity.LS_INFO, tag, message);
  }

  public static void e(String tag, String message) {
    log(Severity.LS_ERROR, tag, message);
  }

  public static void w(String tag, String message) {
    log(Severity.LS_WARNING, tag, message);
  }

  public static void e(String tag, String message, Throwable e) {
    log(Severity.LS_ERROR, tag, message);
    log(Severity.LS_ERROR, tag, e.toString());
    log(Severity.LS_ERROR, tag, getStackTraceString(e));
  }

  public static void w(String tag, String message, Throwable e) {
    log(Severity.LS_WARNING, tag, message);
    log(Severity.LS_WARNING, tag, e.toString());
    log(Severity.LS_WARNING, tag, getStackTraceString(e));
  }

  public static void v(String tag, String message) {
    log(Severity.LS_VERBOSE, tag, message);
  }

  private static String getStackTraceString(Throwable e) {
    if (e == null) {
      return "";
    }

    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    e.printStackTrace(pw);
    return sw.toString();
  }

  private static native void nativeEnableTracing(
      String path, int nativeLevels, int nativeSeverity);
  private static native void nativeEnableLogThreads();
  private static native void nativeEnableLogTimeStamps();
  private static native void nativeLog(int severity, String tag, String message);
}

@@ -515,174 +515,758 @@
 et;%0A
-%0A/** Java wrapper for WebRTC logging. */%0Apublic class Logging %7B%0A  static %7B%0A    try %7B%0A      System.loadLibrary(%22jingle_peerconnection_so%22);%0A    %7D catch (Throwable t) %7B
+import java.util.logging.ConsoleHandler;%0Aimport java.util.logging.SimpleFormatter;%0Aimport java.util.logging.Handler;%0Aimport java.util.logging.Logger;%0Aimport java.util.logging.Level;%0A%0A/** Java wrapper for WebRTC logging. */%0Apublic class Logging %7B%0A  private static final Logger fallbackLogger = Logger.getLogger(%22org.webrtc.Logging%22);%0A%0A  static %7B%0A    try %7B%0A      System.loadLibrary(%22jingle_peerconnection_so%22);%0A    %7D catch (Throwable t) %7B%0A      // If native logging is unavailable, log to system log.%0A      ConsoleHandler consolehandler = new ConsoleHandler();%0A      consolehandler.setFormatter(new SimpleFormatter());%0A      consolehandler.setLevel(Level.ALL);%0A      fallbackLogger.addHandler(consolehandler);%0A      fallbackLogger.setLevel(Level.FINE);
 %0A   
@@ -2730,24 +2730,412 @@
 owable t) %7B%0A
+      Level level;%0A      switch (severity) %7B%0A        case LS_ERROR:%0A          level = Level.SEVERE;%0A          break;%0A        case LS_WARNING:%0A          level = Level.WARNING;%0A          break;%0A        case LS_INFO:%0A          level = Level.INFO;%0A          break;%0A        default:%0A          level = Level.FINE;%0A          break;%0A      %7D%0A      fallbackLogger.log(level, tag + %22: %22 + message);%0A
     %7D%0A  %7D%0A%0A 

Add system log fallback when native logging is unavailable.