/*
 * Copyright (c) 2013-2025 Hutool Team and hutool.cn
 *
 * 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 cn.hutool.v7.log.engine.console;

import cn.hutool.v7.core.date.DateUtil;
import cn.hutool.v7.core.lang.ansi.Ansi4BitColor;
import cn.hutool.v7.core.lang.ansi.AnsiEncoder;
import cn.hutool.v7.core.reflect.ClassUtil;
import cn.hutool.v7.core.text.StrUtil;
import cn.hutool.v7.log.level.Level;

import java.io.Serial;
import java.util.function.Function;

/**
 * 利用System.out.println()打印彩色日志
 *
 * @author hongda.li, Looly
 * @since 5.8.0
 */
public class ConsoleColorLog extends ConsoleLog {
	@Serial
	private static final long serialVersionUID = 1L;

	/**
	 * 控制台打印类名的颜色代码
	 */
	private static final Ansi4BitColor COLOR_CLASSNAME = Ansi4BitColor.CYAN;

	/**
	 * 控制台打印时间的颜色代码
	 */
	private static final Ansi4BitColor COLOR_TIME = Ansi4BitColor.WHITE;

	/**
	 * 控制台打印正常信息的颜色代码
	 */
	private static final Ansi4BitColor COLOR_NONE = Ansi4BitColor.DEFAULT;

	private static Function<Level, Ansi4BitColor> colorFactory = (level -> switch (level) {
		case DEBUG, INFO -> Ansi4BitColor.GREEN;
		case WARN -> Ansi4BitColor.YELLOW;
		case ERROR -> Ansi4BitColor.RED;
		case TRACE -> Ansi4BitColor.MAGENTA;
		default -> COLOR_NONE;
	});

	/**
	 * 设置颜色工厂，根据日志级别，定义不同的颜色
	 *
	 * @param colorFactory 颜色工厂函数
	 */
	public static void setColorFactory(final Function<Level, Ansi4BitColor> colorFactory) {
		ConsoleColorLog.colorFactory = colorFactory;
	}

	/**
	 * 构造
	 *
	 * @param name 类名
	 */
	public ConsoleColorLog(final String name) {
		super(name);
	}

	/**
	 * 构造
	 *
	 * @param clazz 类
	 */
	public ConsoleColorLog(final Class<?> clazz) {
		super(clazz);
	}

	@Override
	public synchronized void log(final String fqcn, final Level level, final Throwable t, final String format, final Object... arguments) {
		if (!isEnabled(level)) {
			return;
		}

		final String template = AnsiEncoder.encode(COLOR_TIME, "[%s]", colorFactory.apply(level), "[%-5s]%s", COLOR_CLASSNAME, "%-30s: ", COLOR_NONE, "%s%n");
		System.out.format(template, DateUtil.formatNow(), level.name(), " - ", ClassUtil.getShortClassName(getName()), StrUtil.format(format, arguments));
	}
}
