// ***************************************************************************************************************************
// * 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.juneau.rest.mock;

import static org.apache.juneau.internal.ExceptionUtils.*;

import java.io.*;
import java.util.*;
import java.util.logging.*;
import java.util.logging.Formatter;

import org.apache.juneau.assertions.*;

/**
 * Simplified logger for intercepting and asserting logging messages.
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Instantiate a mock logger.</jc>
 * 	MockLogger logger = <jk>new</jk> MockLogger();
 *
 * 	<jc>// Associate it with a MockRestClient.</jc>
 * 	MockRestClient
 * 		.<jsm>create</jsm>(MyRestResource.<jk>class</jk>)
 * 		.simpleJson()
 * 		.logger(logger)
 * 		.logRequests(DetailLevel.<jsf>FULL</jsf>, Level.<jsf>SEVERE</jsf>)
 * 		.build()
 * 		.post(<js>"/bean"</js>, bean)
 * 		.complete();
 *
 * 	<jc>// Assert that logging occurred.</jc>
 * 	logger.assertLastLevel(Level.<jsf>SEVERE</jsf>);
 * 	logger.assertLastMessage().is(
 * 		<js>"=== HTTP Call (outgoing) ======================================================"</js>,
 * 		<js>"=== REQUEST ==="</js>,
 * 		<js>"POST http://localhost/bean"</js>,
 * 		<js>"---request headers---"</js>,
 * 		<js>"	Accept: application/json+simple"</js>,
 * 		<js>"---request entity---"</js>,
 * 		<js>"	Content-Type: application/json+simple"</js>,
 * 		<js>"---request content---"</js>,
 * 		<js>"{f:1}"</js>,
 * 		<js>"=== RESPONSE ==="</js>,
 * 		<js>"HTTP/1.1 200 "</js>,
 * 		<js>"---response headers---"</js>,
 * 		<js>"	Content-Type: application/json"</js>,
 * 		<js>"---response content---"</js>,
 * 		<js>"{f:1}"</js>,
 * 		<js>"=== END ======================================================================="</js>,
 * 		<js>""</js>
 * 	);
 * </p>
 */
public class MockLogger extends Logger {

	private static final String FORMAT_PROPERTY = "java.util.logging.SimpleFormatter.format";

	private final List<LogRecord> logRecords = new ArrayList<>();
	private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
	private volatile Formatter formatter;
	private volatile String format = "%4$s: %5$s%6$s%n";

	/**
	 * Constructor.
	 */
	public MockLogger() {
		super("Mock", null);
	}

	/**
	 * Creator.
	 *
	 * @return A new {@link MockLogger} object.
	 */
	public static MockLogger create() {
		return new MockLogger();
	}

	@Override /* Logger */
	public synchronized void log(LogRecord record) {
		logRecords.add(record);
		try {
			baos.write(getFormatter().format(record).getBytes("UTF-8"));
		} catch (Exception e) {
			throw runtimeException(e);
		}
	}

	private Formatter getFormatter() {
		if (formatter == null) {
			synchronized(this) {
				String oldFormat = System.getProperty(FORMAT_PROPERTY);
				System.setProperty(FORMAT_PROPERTY, format);
				formatter = new SimpleFormatter();
				if (oldFormat == null)
					System.clearProperty(FORMAT_PROPERTY);
				else
					System.setProperty(FORMAT_PROPERTY, oldFormat);
			}
		}
		return formatter;
	}

	/**
	 * Sets the level for this logger.
	 *
	 * @param level The new level for this logger.
	 * @return This object (for method chaining).
	 */
	public synchronized MockLogger level(Level level) {
		super.setLevel(level);
		return this;
	}

	/**
	 * Specifies the format for messages sent to the log file.
	 *
	 * <p>
	 * See {@link SimpleFormatter#format(LogRecord)} for the syntax of this string.
	 *
	 * @param format The format string.
	 * @return This object (for method chaining).
	 */
	public synchronized MockLogger format(String format) {
		this.format = format;
		return this;
	}

	/**
	 * Overrides the formatter to use for formatting messages.
	 *
	 * <p>
	 * The default uses {@link SimpleFormatter}.
	 *
	 * @param formatter The log record formatter.
	 * @return This object (for method chaining).
	 */
	public synchronized MockLogger formatter(Formatter formatter) {
		this.formatter = formatter;
		return this;
	}

	/**
	 * Resets this logger.
	 *
	 * @return This object (for method chaining).
	 */
	public synchronized MockLogger reset() {
		logRecords.clear();
		baos.reset();
		return this;
	}

	/**
	 * Asserts that this logger was called.
	 *
	 * @return This object (for method chaining).
	 */
	public synchronized MockLogger assertLogged() {
		if (logRecords.isEmpty())
			throw new AssertionError("Message not logged");
		return this;
	}

	/**
	 * Asserts that the last message was logged at the specified level.
	 *
	 * @param level The level to match against.
	 * @return This object (for method chaining).
	 */
	public synchronized MockLogger assertLastLevel(Level level) {
		assertLogged();
		if (last().getLevel() != level)
			throw new AssertionError("Message logged at [" + last().getLevel() + "] instead of [" + level + "]");
		return this;
	}

	/**
	 * Asserts that the last message matched the specified message.
	 *
	 * @return This object (for method chaining).
	 */
	public synchronized FluentStringAssertion<MockLogger> assertLastMessage() {
		assertLogged();
		return new FluentStringAssertion<>(last().getMessage(), this);
	}

	/**
	 * Asserts that the specified number of messages have been logged.
	 *
	 * @return This object (for method chaining).
	 */
	public synchronized FluentIntegerAssertion<MockLogger> assertRecordCount() {
		return new FluentIntegerAssertion<>(logRecords.size(), this);
	}

	/**
	 * Allows you to perform fluent-style assertions on the contents of the log file.
	 *
	 * @return A new fluent-style assertion object.
	 */
	public synchronized FluentStringAssertion<MockLogger> assertContents() {
		return new FluentStringAssertion<>(baos.toString(), this);
	}

	private LogRecord last() {
		if (logRecords.isEmpty())
			throw new AssertionError("Message not logged");
		return logRecords.get(logRecords.size()-1);
	}

	/**
	 * Returns the contents of this log file as a string.
	 */
	@Override
	public String toString() {
		return baos.toString();
	}
}
