<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Freefactu_Logger {

    private static $log_file;

    /**
     * Initialize the logger system.
     *
     * What this function does:
     * - Creates the log directory in wp-content/uploads/freefactu/
     * - Creates security files (.htaccess and index.php) to protect logs
     * - Sets the log file path
     * - Ensures directory permissions are correct
     *
     * Where it's called from:
     * - freefactu.php: __construct() method
     * - freefactu.php: freefactu_activate() function
     * - class-freefactu-logger.php: log() method if not initialized
     *
     * @return void
     */
    public static function init() {
        $upload_dir = wp_upload_dir();
        $base_dir = $upload_dir['basedir'] . '/freefactu';

        // Create directory if it doesn't exist
        if ( ! Freefactu_Filesystem::exists( $base_dir ) ) {
            $result = Freefactu_Filesystem::mkdir( $base_dir );
            if ( ! $result ) {
                // error_log( "Freefactu Logger: Failed to create log directory at $base_dir" );
                // Continue anyway - set log file path for potential future use
            }
        }

        // Always ensure security files exist (even if directory already existed)
        $htaccess_file = $base_dir . '/.htaccess';
        if ( ! Freefactu_Filesystem::exists( $htaccess_file ) ) {
            Freefactu_Filesystem::put_contents( $htaccess_file, 'Deny from all' );
        }

        $index_file = $base_dir . '/index.php';
        if ( ! Freefactu_Filesystem::exists( $index_file ) ) {
            Freefactu_Filesystem::put_contents( $index_file, '<?php // Silence is golden' );
        }

        self::$log_file = $base_dir . '/freefactu.log';
    }

    /**
     * Log a message to the log file.
     *
     * What this function does:
     * - Writes a formatted log message to the log file
     * - Includes timestamp, log type, and message
     * - Uses file locking to prevent concurrent write issues
     * - Falls back to error_log() if file write fails
     *
     * Where it's called from:
     * - Throughout the plugin for logging errors, warnings, info, and debug messages
     * - class-freefactu-client.php: Multiple locations for AEAT communication logging
     * - class-freefactu-db.php: Database operation logging
     * - class-freefactu-snapshot-utility.php: Snapshot operation logging
     * - And many other files
     *
     * @param string $message The message to log.
     * @param string $type Log type: 'info', 'error', 'warning', or 'debug'.
     * @return void
     */
    public static function log( $message, $type = 'info' ) {
        if ( ! self::$log_file ) {
            self::init();
        }

        $timestamp = current_time( 'mysql' );
        $formatted_message = "[$timestamp] [$type] $message" . PHP_EOL;

        // Use FILE_APPEND for better performance - avoids reading entire file
        $result = @file_put_contents( self::$log_file, $formatted_message, FILE_APPEND | LOCK_EX );

        // If file write fails, fall back to error_log as a safety net
        if ( false === $result ) {
            // error_log( "Freefactu Logger: Failed to write to log file. Message: $formatted_message" );
        }
    }

    /**
     * Get the last N lines from the log file.
     *
     * What this function does:
     * - Reads the last N lines from the log file efficiently
     * - Uses SplFileObject for efficient file reading
     * - Returns lines in reverse chronological order (newest first)
     * - Returns empty array if log file doesn't exist
     *
     * Where it's called from:
     * - class-freefactu-debug.php: render_debug_page() method to display logs
     *
     * @param int $lines Number of lines to retrieve (default: 100).
     * @return array Array of log lines.
     */
    public static function get_logs( $lines = 100 ) {
        if ( ! self::$log_file || ! Freefactu_Filesystem::exists( self::$log_file ) ) {
            return array();
        }

        try {
            // Read last N lines efficiently
            $file = new SplFileObject( self::$log_file, 'r' );
            $file->seek( PHP_INT_MAX );
            $last_line = $file->key();

            $content = array();
            $start = max( 0, $last_line - $lines );

            $file->seek( $start );
            while ( ! $file->eof() ) {
                $line = $file->fgets();
                if ( trim( $line ) ) {
                    $content[] = $line;
                }
            }

            return array_reverse( $content );
        } catch ( Exception $e ) {
            // If file read fails, log to PHP error log and return empty array
            // error_log( "Freefactu Logger: Failed to read log file. Error: " . $e->getMessage() );
            return array();
        }
    }

    /**
     * Clear all log entries.
     *
     * What this function does:
     * - Empties the log file content
     * - Keeps the file structure intact
     * - Logs error if clearing fails
     *
     * Where it's called from:
     * - class-freefactu-debug.php: render_debug_page() method when user clicks "Clear Logs"
     *
     * @return void
     */
    public static function clear_logs() {
        if ( self::$log_file && Freefactu_Filesystem::exists( self::$log_file ) ) {
            $result = Freefactu_Filesystem::put_contents( self::$log_file, '' );
            if ( false === $result ) {
                // error_log( "Freefactu Logger: Failed to clear log file." );
            }
        }
    }

    /**
     * Check if logger is initialized.
     *
     * What this function does:
     * - Returns true if log file path is set
     * - Returns false if logger hasn't been initialized yet
     *
     * Where it's called from:
     * - Not currently used in the codebase (available for future use)
     *
     * @return bool True if initialized, false otherwise.
     */
    public static function is_initialized() {
        return self::$log_file !== null;
    }

    /**
     * Check if the log directory is writable.
     *
     * What this function does:
     * - Checks if log directory exists
     * - Checks if directory is writable
     * - Returns true if both conditions are met
     *
     * Where it's called from:
     * - freefactu.php: check_logger_status() method to display admin notice
     *
     * @return bool True if directory is writable, false otherwise.
     */
    public static function check_directory_writable() {
        if ( ! self::$log_file ) {
            self::init();
        }

        $log_dir = dirname( self::$log_file );
        return Freefactu_Filesystem::exists( $log_dir ) && Freefactu_Filesystem::is_dir( $log_dir ) && Freefactu_Filesystem::is_writable( $log_dir );
    }

    /**
     * Get the log directory path.
     *
     * What this function does:
     * - Returns the directory path where logs are stored
     * - Initializes logger if not already initialized
     *
     * Where it's called from:
     * - freefactu.php: check_logger_status() method to display directory path in admin notice
     *
     * @return string Log directory path.
     */
    public static function get_log_directory() {
        if ( ! self::$log_file ) {
            self::init();
        }
        return dirname( self::$log_file );
    }
}
