<?php

namespace KaizenCoders\MagicLink;

class Logger {
	/**
	 * Log levels
	 */
	const ERROR = 'error';
	const WARNING = 'warning';
	const INFO = 'info';
	const DEBUG = 'debug';

	/**
	 * Log file path
	 */
	private static $log_file;

	/**
	 * Initialize logger
	 */
	public static function init() {
		self::$log_file = KC_ML_LOG_DIR . '/magic-link-' . date( 'Y-m-d' ) . '.log';
	}

	/**
	 * Log a message
	 *
	 * @param  string  $level
	 * @param  string  $message
	 * @param  array   $context
	 */
	private static function log( $level, $message, array $context = [] ) {
		if ( ! is_dir( KC_ML_LOG_DIR ) ) {
			return;
		}

		if ( empty( self::$log_file ) ) {
			self::init();
		}

		$timestamp         = date( 'Y-m-d H:i:s' );
		$formatted_message = self::format_message( $timestamp, $level, $message, $context );

		error_log( $formatted_message . PHP_EOL, 3, self::$log_file );
	}

	/**
	 * Format log message
	 */
	private static function format_message( $timestamp, $level, $message, array $context ) {
		$replace = [];
		foreach ( $context as $key => $val ) {
			if ( is_null( $val ) || is_scalar( $val ) || ( is_object( $val ) && method_exists( $val, '__toString' ) ) ) {
				$replace[ '{' . $key . '}' ] = $val;
			} elseif ( is_array( $val ) ) {
				$replace[ '{' . $key . '}' ] = json_encode( $val );
			}
		}

		$message = strtr( $message, $replace );

		return sprintf( '[%s] %s: %s %s',
			$timestamp,
			strtoupper( $level ),
			$message,
			empty( $context ) ? '' : json_encode( $context )
		);
	}

	/**
	 * Log error message
	 *
	 * @param  string  $message
	 * @param  array   $context
	 */
	public static function error( $message, array $context = [] ) {
		self::log( self::ERROR, $message, $context );
	}

	/**
	 * Log warning message
	 *
	 * @param  string  $message
	 * @param  array   $context
	 */
	public static function warning( $message, array $context = [] ) {
		self::log( self::WARNING, $message, $context );
	}

	/**
	 * Log info message
	 *
	 * @param  string  $message
	 * @param  array   $context
	 */
	public static function info( $message, array $context = [] ) {
		self::log( self::INFO, $message, $context );
	}

	/**
	 * Log debug message
	 *
	 * @param  string  $message
	 * @param  array   $context
	 */
	public static function debug( $message, array $context = [] ) {
		self::log( self::DEBUG, $message, $context );
	}
}