/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.felix.scrplugin.bnd;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.felix.scrplugin.Log;

import aQute.service.reporter.Reporter;

/**
 * Scrplugin Log implementation, which redirects log to both bnd "Reporter" and
 * to /tmp/scrplugin/<BundleSymbolicName>.log
 */
public class BndLog implements Log {
	/**
	 * The BndLib logging reported.
	 */
	private final Reporter reporter;

	/**
	 * Enabled log level, which can be configured in bnd scrplugin declaration.
	 */
	private Level logEnabled = Level.Warn;

	/**
	 * Writer to log file, in tmp dir/scrplugin-BSN.log
	 */
	private final PrintWriter logWriter;

	/**
	 * DateFormat used when logging.
	 */
	private final static SimpleDateFormat dateFormat = new SimpleDateFormat(
			"E yyyy.MM.dd hh:mm:ss.S");
	
	/**
	 * Log Levels.
	 */
	enum Level {
		Error, Warn, Info, Debug
	}

	/**
	 * Creates a new bnd Log implementaiton
	 * 
	 * @param reporter
	 *            the bnd logger
	 * @param logLevel
	 * @param bsn
	 */
	BndLog(Reporter reporter, String bsn) {
		this.reporter = reporter;
		File logFilePath = new File(System.getProperty("java.io.tmpdir")
				+ File.separator + "scrplugin" + File.separator + bsn + ".log");
		new File(logFilePath.getParent()).mkdirs();
		
		PrintWriter writer = null;
		try {
			writer = new PrintWriter(new FileWriter(logFilePath, false));
		} catch (IOException e) {
			reporter.exception(e, "Could not create scrplugin log file: %s",
					logFilePath);
			writer = null;
		}
		this.logWriter = writer;
	}

	/**
	 * Close log file.
	 */
	public void close() {
		if (logWriter != null) {
			logWriter.close();
		}
	}

	/**
	 * Sets the enabled log level.
	 * 
	 * @param level
	 *            the enabled level ("Error", "Warn", "Info", or "Debug")
	 */
	public void setLevel(String level) {
		try {
			level = Character.toUpperCase(level.charAt(0))
					+ level.substring(1).toLowerCase();
			this.logEnabled = Level.valueOf(level);
		} catch (IllegalArgumentException e) {
			this.logEnabled = Level.Warn;
			warn("Bnd scrplugin logger initialized with invalid log level: "
					+ level);
		}
	}

	// Reporter

	public boolean isDebugEnabled() {
		return logEnabled.ordinal() >= Level.Debug.ordinal();
	}

	public boolean isInfoEnabled() {
		return logEnabled.ordinal() >= Level.Info.ordinal();
	}

	public boolean isWarnEnabled() {
		return logEnabled.ordinal() >= Level.Warn.ordinal();
	}

	public boolean isErrorEnabled() {
		return logEnabled.ordinal() >= Level.Error.ordinal();
	}

	public void debug(String content) {
		if (isDebugEnabled()) {
			reporter.trace("%s", content);
			logDebug(content, null);
		}
	}

	public void debug(String content, Throwable error) {
		if (isDebugEnabled()) {
			reporter.trace("%s:%s", content, toString(error));
			logDebug(content, error);
		}
	}

	public void debug(Throwable error) {
		if (isDebugEnabled()) {
			reporter.trace("%s", toString(error));
			logDebug("exception", error);
		}
	}

	public void info(String content) {
		if (isInfoEnabled()) {
			reporter.trace("%s", content);
			logInfo(content, null);
		}
	}

	public void info(String content, Throwable error) {
		if (isInfoEnabled()) {
			reporter.trace("%s:%s", content, toString(error));
			logInfo(content, error);
		}
	}

	public void info(Throwable error) {
		if (isInfoEnabled()) {
			reporter.trace("%s", toString(error));
			logInfo("exception:", error);
		}
	}

	public void warn(String content) {
		if (isWarnEnabled()) {
			reporter.warning("%s", content);
			logWarn(content, null);
		}
	}

	public void warn(String content, Throwable error) {
		if (isWarnEnabled()) {
			reporter.warning("%s:%s", content, toString(error));
			logWarn(content, error);
		}
	}

	public void warn(Throwable error) {
		if (isWarnEnabled()) {
			reporter.warning("%s", toString(error));
			logWarn("exception:", error);
		}
	}

	public void warn(String content, String location, int lineNumber) {
		warn(String.format("%s [%s,%d]", content, location, lineNumber));
	}

	public void warn(String content, String location, int lineNumber,
			int columNumber) {
		warn(String.format("%s [%s,%d:%d]", content, location, lineNumber,
				columNumber));
	}

	public void error(String content) {
		reporter.error("%s", content);
		logErr(content, null);
	}

	public void error(String content, Throwable error) {
		reporter.error("%s:%s", content, toString(error));
		logErr(content, error);
	}

	public void error(Throwable error) {
		reporter.error("%s", toString(error));
		logErr("exception:", error);
	}

	public void error(String content, String location, int lineNumber) {
		error(String.format("%s [%s,%d]", content, location, lineNumber));
	}

	public void error(String content, String location, int lineNumber,
			int columnNumber) {
		error(String.format("%s [%s,%d:%d]", content, location, lineNumber,
				columnNumber));
	}

	private void logErr(String msg, Throwable t) {
		log(Level.Error, msg, t);
	}

	private void logWarn(String msg, Throwable t) {
		log(Level.Warn, msg, t);
	}

	private void logInfo(String msg, Throwable t) {
		log(Level.Info, msg, t);
	}

	private void logDebug(String msg, Throwable t) {
		log(Level.Debug, msg, t);
	}

	private void log(Level level, String msg, Throwable t) {
		if (logWriter != null) {
			StringBuilder sb = new StringBuilder();
			sb.append(dateFormat.format(new Date()));
			sb.append(" - ");
			sb.append(level);
			sb.append(": ");
			sb.append(msg);
			if (t != null) {
				sb.append(" - ").append(toString(t));
			}
			logWriter.println(sb.toString());
		}
	}

	private static String toString(Throwable e) {
		StringWriter buffer = new StringWriter();
		PrintWriter pw = new PrintWriter(buffer);
		e.printStackTrace(pw);
		return (buffer.toString());
	}
}
