/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* Copyright (c) 2025 Brett A C Sheffield <bacs@librecast.net> */

#include <log.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

int log_close(state_t *state)
{
	if (state->log && fclose(state->log)) return -1;
	return state->log = NULL, 0;
}

int log_open(state_t *state, const char *filename)
{
	const char *logfile = (filename) ? filename : state->logfile;
	if (!logfile) return (state->log = stderr), 0;
	state->log = fopen(logfile, "a");
	if (filename) state->logfile = (char *)filename;
	if (state->log == NULL) {
		perror("fopen");
		return -1;
	}
	return 0;
}

int log_write(state_t *state, const char *fmt, ...)
{
	va_list ap;
	if (!state->log && log_open(state, NULL)) return -1;

	/* if using a logfile or on a terminal */
	if (state->logfile || isatty(fileno(state->log))) {
		/* output ISO8601 date */
		char s[] = "1900-12-31T23:59:59.999+0000";
		struct timeval tv;
		struct timezone tz;
		struct tm *local;
		size_t off = 0;
		if (gettimeofday(&tv, &tz) == -1) return -1;
		local = localtime(&tv.tv_sec);
		off = strftime(s, sizeof s - off, "%FT%T", local);
		off += snprintf(s + off, sizeof s - off, ".%03ld", (long int)tv.tv_usec/1000);
		off += strftime(s + off, sizeof s - off, "%z", local);
		fflush(state->log);
		fprintf(state->log, "%s ", s);
	}

	va_start(ap, fmt);
	vfprintf(state->log, fmt, ap);
	va_end(ap);
	fflush(state->log);
	return 0;
}
