<?php

namespace RSSSL\Pro\Security\WordPress\Firewall;

class Rsssl_Firewall_File_Handler
{
    /**
     * Is used for the filesystem path to the firewall file in wp-content.
     */
    private string $file_path;

    /**
     * Constructor.
     * Sets the file path to wp-content/firewall.php.
     */
    public function __construct()
    {
        $wpContentPath = ( defined( 'WP_CONTENT_DIR' ) ? trailingslashit( WP_CONTENT_DIR ) : '' );
        if ( empty( $wpContentPath ) ) {
            $wpContentPath = ABSPATH . '/wp-content/';
        }
        $this->file_path = apply_filters( 'rsssl_firewall_file_path', $wpContentPath . 'firewall.php' );
    }

    /**
     * Creates the firewall file if it does not already exist.
     */
    public function create(): bool
    {
        //checking if the file already exists if so we do nothing.
        if (is_file($this->file_path)) {
            return true;
        }

        // We set the base content of the file
        $data = "<?php" . PHP_EOL;
        $data .= "// This file is generated by the Really Simple Security Pro plugin" . PHP_EOL;
        $data .= "// Do not modify this file manually" . PHP_EOL;


        // Writing the content to the file
        $result = file_put_contents($this->file_path, $data, LOCK_EX);
        // Checking if the file is written successfully
        return ($result !== false);
    }

    /**
     * Reads the firewall file and returns its content.
     */
    public function read(): string
    {
        // Reading the content of the file
        return file_get_contents($this->file_path);
    }

    /**
     * Deletes the firewall file if it exists.
     */
    public function delete(): bool
    {
        // Check if the file exists before attempting deletion
        if (!is_file($this->file_path)) {
            return false;
        }
        return unlink($this->file_path);
    }

    /**
     * Adds a section of logic to the firewall file by marker.
     *
     * @uses insert_with_markers
     */
    public function addSectionByMarker(string $marker, string $lines): bool
    {
        if (!is_file($this->file_path)) {
            return false;
        }

        // Make sure the WordPress function is available.
        if ( ! function_exists( 'insert_with_markers' ) ) {
            require_once( ABSPATH . 'wp-admin/includes/misc.php' );
        }

        // Convert the lines string into an array by splitting on newlines
        $arrayOfLinesToInsert = preg_split("/\r\n|\n|\r/", $lines);
        // Insert the data into the file and capture the result
        $inserted = insert_with_markers($this->file_path, $marker, $arrayOfLinesToInsert);

        // Prepare a log message with success or failure status
        $logMessage = sprintf(
            '[Rsssl_Firewall_file_Handler] %s %s',
            $inserted
                ? 'Custom firewall logic successfully added to'
                : 'Failed to add firewall logic to',
            $this->file_path
        );

        // Log the outcome
      //  error_log($logMessage);

        return $inserted;
    }

    /**
     * Removes a section with the specified marker from the firewall file.
     *
     * Used to clear custom firewall logic sections added via addSectionByMarker.
     *
     * @uses insert_with_markers
     */
    public function removeSectionByMarker(string $marker): bool
    {
        if ( ! is_file( $this->file_path ) ) {
            return false;
        }

        // Ensure the WordPress insert_with_markers function is available.
        if ( ! function_exists( 'insert_with_markers' ) ) {
            require_once( ABSPATH . 'wp-admin/includes/misc.php' );
        }

        // Remove the section and capture the result.
        $removed = insert_with_markers( $this->file_path, $marker, [] );

        // Prepare a log message with success or failure status.
        $logMessage = sprintf(
            '[Rsssl_Firewall_file_Handler] %s %s',
            $removed
                ? 'Custom firewall logic removed from'
                : 'Failed to remove firewall logic from',
            $this->file_path
        );

        // Log the outcome.
        error_log( $logMessage );

        return $removed;
    }

	/**
	 * Use this method to add multiple sections with different markers to the firewall.php
	 * Currently used by {@see Rsssl_Geo_Block::generate_firewall_rules()} to do X
	 *
	 * @param array $sections ['marker' => 'lines', 'marker2' => 'lines']
	 * @uses addSectionByMarker
	 */
    public function addSectionsByMarkers(array $sections): void
    {
        foreach ($sections as $marker => $lines) {
            $this->addSectionByMarker($marker, $lines);
        }
    }
}