/*
 * 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.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;

import java.util.logging.LogRecord;

/**
 * A set of functions to convert SerializableLogRecords into JSON strings.
 * The corresponding functions to convert them back are in
 * JsonLogRecordServerUtil.java.  This class should only be used in client
 * side code since it imports com.google.gwt.json.client classes.
 * TODO(unnurg) once there is a unified JSON GWT library, combine this with
 * JsonLogRecordServerUtil.
 */
public class JsonLogRecordClientUtil {

  public static String logRecordAsJson(LogRecord lr) {
    return logRecordAsJsonObject(lr).toString();
  }
  
  private static JSONString getJsonString(String s) {
    if (s == null) {
      return new JSONString("");
    }
    return new JSONString(s);
  }

  private static JSONObject logRecordAsJsonObject(LogRecord lr) {
    JSONObject obj = new JSONObject();
    obj.put("level", getJsonString(lr.getLevel().toString()));
    obj.put("loggerName", getJsonString(lr.getLoggerName()));
    obj.put("msg", getJsonString(lr.getMessage()));
    obj.put("timestamp", new JSONString("" + lr.getMillis()));
    obj.put("thrown", throwableAsJsonObject(lr.getThrown()));
    return obj;
  }
  
  private static JSONObject stackTraceElementAsJsonObject(
      StackTraceElement e) {
    JSONObject obj = new JSONObject();
    if (e != null) {
      obj.put("className", getJsonString(e.getClassName()));
      obj.put("fileName", getJsonString(e.getFileName()));
      obj.put("methodName", getJsonString(e.getMethodName()));
      obj.put("lineNumber", getJsonString("" + e.getLineNumber()));
    }
    return obj;
  }
  
  private static JSONObject throwableAsJsonObject(Throwable t) {
    JSONObject obj = new JSONObject();
    if (t != null) {
      obj.put("message", getJsonString(t.getMessage()));
      obj.put("cause", throwableAsJsonObject(t.getCause()));
      StackTraceElement[] stackTrace = t.getStackTrace();
      if (stackTrace != null && stackTrace.length > 0) {
        JSONArray arr = new JSONArray();
        for (int i = 0; i < stackTrace.length; i++) {
          arr.set(i, stackTraceElementAsJsonObject(stackTrace[i]));
        }
        obj.put("stackTrace", arr);
      }
    }
    return obj;
  }
}
