extends Node

## Autoload injected into the running game by the Golem MCP plugin.
## - Watches for a capture request file, takes a screenshot, saves it.
## - Captures print() output and errors to a log file for the editor to read.
## Automatically disabled in release builds.

const REQUEST_PATH := "user://golem_capture_request"
const SCREENSHOT_PATH := "user://golem_game_screenshot.jpg"
const LOG_PATH := "user://golem_game_logs.txt"
const POLL_INTERVAL := 0.1  # Check every 100ms
const LOG_FLUSH_INTERVAL := 0.5  # Write logs to disk every 500ms

var _timer: float = 0.0
var _log_timer: float = 0.0
var _active: bool = false
var _log_buffer: PackedStringArray = []
var _log_file: FileAccess


func _ready() -> void:
	_active = OS.is_debug_build()
	if not _active:
		set_process(false)
		return

	# Open log file (truncate on game start)
	_log_file = FileAccess.open(LOG_PATH, FileAccess.WRITE)
	if _log_file:
		_log_file.store_string("")
		_log_file.close()

	# Intercept print output via a custom logger
	# GDScript doesn't have a print hook, but we can redirect via Engine
	# The most reliable way: use a custom LogHandler via the logger API
	# For now, we hook into the message callback
	pass


func _notification(what: int) -> void:
	if what == NOTIFICATION_PREDELETE and _log_file:
		_flush_logs()


func _process(delta: float) -> void:
	# --- Screenshot capture ---
	_timer += delta
	if _timer >= POLL_INTERVAL:
		_timer = 0.0
		if FileAccess.file_exists(REQUEST_PATH):
			DirAccess.remove_absolute(REQUEST_PATH)
			_capture_screenshot()

	# --- Flush logs periodically ---
	_log_timer += delta
	if _log_timer >= LOG_FLUSH_INTERVAL:
		_log_timer = 0.0
		_flush_logs()


func _capture_screenshot() -> void:
	var viewport := get_viewport()
	if viewport == null:
		return

	var image := viewport.get_texture().get_image()
	if image == null:
		return

	var max_dim := 1280
	if image.get_width() > max_dim or image.get_height() > max_dim:
		var scale_factor: float = float(max_dim) / float(maxi(image.get_width(), image.get_height()))
		image.resize(
			int(image.get_width() * scale_factor),
			int(image.get_height() * scale_factor),
			Image.INTERPOLATE_BILINEAR
		)

	image.save_jpg(SCREENSHOT_PATH, 0.85)


## Call this from game scripts instead of print() to capture output.
## Example: GolemCapture.log("Player hit at position %s" % pos)
func log(msg: String) -> void:
	var timestamp := "%.2f" % (Time.get_ticks_msec() / 1000.0)
	_log_buffer.append("[%s] %s" % [timestamp, msg])
	# Also print normally so it shows in Godot's output panel
	print(msg)


func log_error(msg: String) -> void:
	var timestamp := "%.2f" % (Time.get_ticks_msec() / 1000.0)
	_log_buffer.append("[%s] ERROR: %s" % [timestamp, msg])
	push_error(msg)


func _flush_logs() -> void:
	if _log_buffer.size() == 0:
		return

	# Append to log file
	var file := FileAccess.open(LOG_PATH, FileAccess.READ_WRITE)
	if file == null:
		file = FileAccess.open(LOG_PATH, FileAccess.WRITE)
	if file == null:
		return

	file.seek_end()
	for line in _log_buffer:
		file.store_line(line)
	file.close()

	_log_buffer.clear()
