// ***************************************************************************************************************************
// * 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;

import static org.apache.juneau.rest.Enablement.*;

import java.util.*;
import java.util.logging.*;

import javax.servlet.http.*;

import org.apache.juneau.*;
import org.apache.juneau.json.*;

/**
 * Represents a set of logging rules for how to handle logging of HTTP requests/responses.
 */
public class RestCallLoggerConfig {

	/**
	 * Default empty logging config.
	 */
	public static final RestCallLoggerConfig DEFAULT = RestCallLoggerConfig.create().build();

	/**
	 * Default debug logging config.
	 */
	public static final RestCallLoggerConfig DEFAULT_DEBUG =
		RestCallLoggerConfig
			.create()
			.useStackTraceHashing(false)
			.level(Level.WARNING)
			.rules(
				RestCallLoggerRule
					.create()
					.codes("*")
					.verbose()
					.build()
			)
			.build();

	private final RestCallLoggerRule[] rules;
	private final boolean useStackTraceHashing;
	private final Enablement disabled;
	private final int stackTraceHashingTimeout;
	private final Level level;

	RestCallLoggerConfig(Builder b) {
		RestCallLoggerConfig p = b.parent;

		this.disabled = b.disabled != null ? b.disabled : p != null ? p.disabled : FALSE;
		this.useStackTraceHashing = b.useStackTraceHashing != null ? b.useStackTraceHashing : p != null ? p.useStackTraceHashing : false;
		this.stackTraceHashingTimeout = b.stackTraceHashingTimeout != null ? b.stackTraceHashingTimeout : p != null ? p.stackTraceHashingTimeout : Integer.MAX_VALUE;
		this.level = b.level != null ? b.level : p != null ? p.level : Level.INFO;

		ArrayList<RestCallLoggerRule> rules = new ArrayList<>();
		rules.addAll(b.rules);
		if (p != null)
			rules.addAll(Arrays.asList(p.rules));
		this.rules = rules.toArray(new RestCallLoggerRule[rules.size()]);
	}

	/**
	 * Creates a builder for this class.
	 *
	 * @return A new builder for this class.
	 */
	public static Builder create() {
		return new Builder();
	}

	/**
	 * Builder for {@link RestCallLoggerConfig} objects.
	 */
	public static class Builder {
		List<RestCallLoggerRule> rules = new ArrayList<>();
		RestCallLoggerConfig parent;
		Level level;
		Boolean useStackTraceHashing;
		Enablement disabled;
		Integer stackTraceHashingTimeout;

		/**
		 * Sets the parent logging config.
		 *
		 * @param parent
		 * 	The parent logging config.
		 * 	<br>Can be <jk>null</jk>.
		 * @return This object (for method chaining).
		 */
		public Builder parent(RestCallLoggerConfig parent) {
			this.parent = parent;
			return this;
		}

		/**
		 * Adds a new logging rule to this config.
		 *
		 * <p>
		 * 	The rule will be added to the END of list of current rules and thus checked last in the current list but
		 * 	before any parent rules.
		 *
		 * @param rule The logging rule to add to this config.
		 * @return This object (for method chaining).
		 */
		public Builder rule(RestCallLoggerRule rule) {
			this.rules.add(rule);
			return this;
		}

		/**
		 * Adds new logging rules to this config.
		 *
		 * <p>
		 * 	The rules will be added in order to the END of list of current rules and thus checked last in the current list but
		 * 	before any parent rules.
		 *
		 * @param rules The logging rules to add to this config.
		 * @return This object (for method chaining).
		 */
		public Builder rules(RestCallLoggerRule...rules) {
			for (RestCallLoggerRule rule : rules)
				this.rules.add(rule);
			return this;
		}

		/**
		 * Enables no-trace mode on this config.
		 *
		 * <p>
		 * No-trace mode prevents logging of messages to the log file.
		 *
		 * <p>
		 * Possible values (case-insensitive):
		 * <ul>
		 * 	<li>{@link Enablement#TRUE TRUE} - No-trace mode enabled for all requests.
		 * 	<li>{@link Enablement#FALSE FALSE} - No-trace mode disabled for all requests.
		 * 	<li>{@link Enablement#PER_REQUEST PER_REQUEST} - No-trace mode enabled for requests that have a <js>"X-NoTrace: true"</js> header.
		 * </ul>
		 *
		 * @param value
		 * 	The value for this property.
		 * 	<br>Can be <jk>null</jk> (inherit from parent or default to {@link Enablement#FALSE NEVER}).
		 * @return This object (for method chaining).
		 */
		public Builder disabled(Enablement value) {
			this.disabled = value;
			return this;
		}

		/**
		 * Shortcut for calling <c>disabled(<jsf>TRUE</jsf>)</c>.
		 *
		 * @return This object (for method chaining).
		 */
		public Builder disabled() {
			return disabled(TRUE);
		}

		/**
		 * Enables the use of stacktrace hashing.
		 *
		 * <p>
		 * When enabled, stacktraces will be replaced with hashes in the log file.
		 *
		 * @param value
		 * 	The value for this property.
		 * 	<br>Can be <jk>null</jk> (inherit from parent or default to <jk>false</jk>).
		 * @return This object (for method chaining).
		 */
		public Builder useStackTraceHashing(Boolean value) {
			this.useStackTraceHashing = value;
			return this;
		}

		/**
		 * Shortcut for calling <c>useStackTraceHashing(<jk>true</jk>);</c>.
		 *
		 * @return This object (for method chaining).
		 */
		public Builder useStackTraceHashing() {
			this.useStackTraceHashing = true;
			return this;
		}

		/**
		 * Enables a timeout after which stack traces hashes are flushed.
		 *
		 * @param timeout
		 * 	Time in milliseconds to hash stack traces for.
		 * 	<br>Can be <jk>null</jk> (inherit from parent or default to {@link Integer#MAX_VALUE MAX_VALUE}).
		 * @return This object (for method chaining).
		 */
		public Builder stackTraceHashingTimeout(Integer timeout) {
			this.stackTraceHashingTimeout = timeout;
			return this;
		}

		/**
		 * The default logging level.
		 *
		 * <p>
		 * This defines the logging level for messages if they're not already defined on the matched rule.
		 *
		 * @param value
		 * 	The value for this property.
		 * 	<br>Can be <jk>null</jk> (inherit from parent or default to {@link Level#INFO INFO}).
		 * @return This object (for method chaining).
		 */
		public Builder level(Level value) {
			this.level = value;
			return this;
		}

		/**
		 * Applies the properties in the specified object map to this builder.
		 *
		 * @param m The map containing properties to apply.
		 * @return This object (for method chaining).
		 */
		public Builder apply(ObjectMap m) {
			for (String key : m.keySet()) {
				if ("useStackTraceHashing".equals(key))
					useStackTraceHashing(m.getBoolean("useStackTraceHashing"));
				else if ("stackTraceHashingTimeout".equals(key))
					stackTraceHashingTimeout(m.getInt("stackTraceHashingTimeout"));
				else if ("disabled".equals(key))
					disabled(m.get("disabled", Enablement.class));
				else if ("rules".equals(key))
					rules(m.get("rules", RestCallLoggerRule[].class));
				else if ("level".equals(key))
					level(m.get("level", Level.class));
			}
			return this;
		}

		/**
		 * Creates the {@link RestCallLoggerConfig} object based on settings on this builder.
		 *
		 * @return A new {@link RestCallLoggerConfig} object.
		 */
		public RestCallLoggerConfig build() {
			return new RestCallLoggerConfig(this);
		}
	}

	/**
	 * Given the specified servlet request/response, find the rule that applies to it.
	 *
	 * @param req The servlet request.
	 * @param res The servlet response.
	 * @return The applicable logging rule, or <jk>null</jk> if a match could not be found.
	 */
	public RestCallLoggerRule getRule(HttpServletRequest req, HttpServletResponse res) {

		int status = res.getStatus();
		Throwable e = (Throwable)req.getAttribute("Exception");
		boolean debug = isDebug(req);

		for (RestCallLoggerRule r : rules) {
			if (r.matches(status, debug, e)) {
				Enablement disabled = r.getDisabled();
				if (disabled == null)
					disabled = this.disabled;
				if (disabled == TRUE)
					return null;
				if (isNoTraceAttr(req))
					return null;
				if (disabled == FALSE)
					return r;
				if (isNoTraceHeader(req))
					return null;
				return r;
			}
		}

		return null;
	}

	/**
	 * Returns <jk>true</jk> if logging is disabled for this request.
	 *
	 * @param req The HTTP request.
	 * @return <jk>true</jk> if logging is disabled for this request.
	 */
	public boolean isDisabled(HttpServletRequest req) {
		if (disabled == TRUE)
			return true;
		if (disabled == FALSE)
			return false;
		return isNoTraceAttr(req);
	}

	private boolean isDebug(HttpServletRequest req) {
		Boolean b = boolAttr(req, "Debug");
		return (b != null && b == true);
	}

	private boolean isNoTraceAttr(HttpServletRequest req) {
		Boolean b = boolAttr(req, "NoTrace");
		return (b != null && b == true);
	}

	private boolean isNoTraceHeader(HttpServletRequest req) {
		return "true".equalsIgnoreCase(req.getHeader("X-NoTrace"));
	}

	/**
	 * Returns the default logging level.
	 *
	 * @return The default logging level.
	 */
	public Level getLevel() {
		return level;
	}

	/**
	 * Returns <jk>true</jk> if stack traces should be hashed.
	 *
	 * @return <jk>true</jk> if stack traces should be hashed.
	 */
	public boolean isUseStackTraceHashing() {
		return useStackTraceHashing;
	}

	/**
	 * Returns the time in milliseconds that stacktrace hashes should be persisted.
	 *
	 * @return The time in milliseconds that stacktrace hashes should be persisted.
	 */
	public int getStackTraceHashingTimeout() {
		return stackTraceHashingTimeout;
	}

	/**
	 * Returns the rules defined in this config.
	 *
	 * @return Thew rules defined in this config.
	 */
	public List<RestCallLoggerRule> getRules() {
		return Collections.unmodifiableList(Arrays.asList(rules));
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Other methods
	//-----------------------------------------------------------------------------------------------------------------

	private Boolean boolAttr(HttpServletRequest req, String name) {
		Object o = req.getAttribute(name);
		if (o == null || ! (o instanceof Boolean))
			return null;
		return (Boolean)o;
	}

	@Override /* Object */
	public String toString() {
		return SimpleJsonSerializer.DEFAULT_READABLE.toString(toMap());
	}

	/**
	 * Returns the properties defined on this bean context as a simple map for debugging purposes.
	 *
	 * @return A new map containing the properties defined on this context.
	 */
	public ObjectMap toMap() {
		return new DefaultFilteringObjectMap()
			.append("useStackTraceHashing", useStackTraceHashing)
			.append("disabled", disabled == FALSE ? null : disabled)
			.append("stackTraceHashingTimeout", stackTraceHashingTimeout == Integer.MAX_VALUE ? null : stackTraceHashingTimeout)
			.append("level", level == Level.INFO ? null : level)
			.append("rules", rules.length == 0 ? null : rules)
		;
	}
}
