-- vg_logging/init.lua
-- Create logging functions for mods easily
-- Copyright (C) 2024 1F616EMO
-- Copyright (C) 2024 Mikita 'rudzik8' Wiśniewski
-- SPDX-License-Identifier: LGPL-2.1-or-later
local core, error, format = core, error, string.format

local DEBUG = core.settings:get_bool("vg.debug", false)

local function format_message(mod, msg, ...)
	msg = type(msg) ~= "string" and dump(msg) or msg

	local n = select("#", ...)
	if n > 0 then
		msg = format(msg, ...)
	end

	return table.concat{"[", mod, "] ", msg}
end

local index_table = {}

-- Any level
index_table.log = function(self, lvl, msg, ...)
	return core.log(lvl, format_message(self.mod, msg, ...))
end

-- Normal loggings
for _, lvl in ipairs{"none", "error", "warning", "action", "info", "verbose"} do
	index_table[lvl] = function(self, msg, ...)
		return core.log(lvl, format_message(self.mod, msg, ...))
	end
end

-- Debug
if DEBUG then
	local function concat_args(...)
		local t = {}
		for _, arg in ipairs{...} do
			table.insert(t, (type(arg) ~= "string" and type(arg) ~= "number") and dump(arg) or arg)
		end
		return table.concat(t, "\t")
	end

	index_table.debug = function(self, ...)
		return self:none(concat_args(...))
	end
else
	-- Debug is disabled, provide a dummy
	index_table.debug = function() end
end

-- Raise error
index_table.raise = function(self, msg, ...)
	return error(format_message(self.mod, msg, ...), 2)
end

-- Assertion
index_table.assert = function(self, condition, msg, ...)
	if not msg then
		msg = "Assertion failed!"
	end
	return assert(condition, format_message(self.mod, msg, ...))
end

-- Create sublogger
index_table.sublogger = function(self, name)
	return voxelgarden.get_logger(self.mod .. "." .. name)
end

-- Initialize metatable
local metatable = {}
metatable.__index = index_table
metatable.__newindex = function(self)
	error("Attempt to set new field in logger " .. self.mod, 2)
end
metatable.__call = index_table.none

function voxelgarden.get_logger(mod)
	if not mod or not core.get_modpath(mod) then
		mod = core.get_current_modname() or "???"
	end
	return setmetatable({mod = mod}, metatable)
end

-- Expose `format_message`
vg_logging = {
	format_message = format_message
}

local self_logger = voxelgarden.get_logger("vg_logging")

self_logger:action("Loaded %s", "logging mod")
