<?php
declare(strict_types=1);

/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link      https://cakephp.org CakePHP(tm) Project
 * @since     0.2.9
 * @license   https://opensource.org/licenses/mit-license.php MIT License
 */
namespace App\Controller;

use Cake\Controller\Controller;
use Cake\Event\EventInterface;


/**
 * Application Controller
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @link https://book.cakephp.org/4/en/controllers.html#the-app-controller
 */
class AppController extends Controller
{
    /**
     * Initialization hook method.
     *
     * Use this method to add common initialization code like loading components.
     *
     * e.g. `$this->loadComponent('FormProtection');`
     *
     * @return void
     */
    public function initialize(): void
    {
        parent::initialize();

        $this->Menus = $this->fetchTable('Menus');
        $this->Contacts = $this->fetchTable('Contacts');

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');

        /*
         * Enable the following component for recommended CakePHP form protection settings.
         * see https://book.cakephp.org/4/en/controllers/components/form-protection.html
         */
        $this->loadComponent('FormProtection');
    }
    
        /**
     * Executes before the controller action.
     *
     * This method is called before each action in the controller. It is used to set various response headers
     * that enhance the security and privacy of the application. The following headers are set:
     *
     * - `Feature-Policy`: Restricts the use of certain features (in this case, geolocation) to the same origin.
     * - `Content-Security-Policy`: Enforces trusted types for script execution, which helps prevent Cross-Site Scripting (XSS) attacks.
     * - `Cache-Control`: Instructs the browser not to cache the response.
     * - `Referrer-Policy`: Specifies how much referrer information should be included with requests made from the document.
     *
     * @param \Cake\Event\EventInterface $event The event that was triggered.
     * @return void
     */
    public function beforeFilter(EventInterface $event)
    {
        parent::beforeFilter($event);

        $this->response = $this->response->withHeader('Feature-Policy', "geolocation 'self'");

        $response = $this->response->withHeader(
            'Content-Security-Policy',
            "require-trusted-types-for 'script';"
        );

        $this->response = $this->response->withHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');

        // Set the Referrer Policy header
        $this->response = $this->response->withHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
    }

    /**
     * This method is called before the view is rendered.
     *
     * It retrieves application settings, contact information, and URL parameters,
     * then sets these values to be available in the view.
     *
     * @param \Cake\Event\EventInterface $event The event instance being triggered.
     *
     * @return void
     */
    public function beforeRender(EventInterface $event)
    {
        parent::beforeRender($event);

        $this->getMenu();

        $appSettings = $this->getTableLocator()->get('AppSettings')->find()
            ->cache('app_settings_cache')
            ->all()
            ->combine("setting_name", "setting_value")
            ->toArray();

        $contacts = $this->getTableLocator()->get('Contacts')
            ->find()
            ->first();

        $urlParams = $this->getRequest()->getAttribute('params');

        $this->set(compact('appSettings', 'contacts', 'urlParams'));

        // Fetch the nonce and pass it to the view globally
        $this->set('styleNonce', $this->request->getAttribute('cspStyleNonce'));

        // Fetch the nonce and pass it to the view globally
        $this->set('scriptNonce', $this->request->getAttribute('cspScriptNonce'));
    }


    /**
     * Retrieves the main and footer menus and sets them for the view.
     *
     * This method fetches the main menus using the Menus model and retrieves
     * the footer menus from the Menus table. The menus are then set to be
     * accessible in the view.
     *
     * @return void
     */
    public function getMenu()
    {
        $menus = $this->Menus->getMainMenus();

        $footerMenus = $this->getTableLocator()->get('Menus')->getFooterMenus();

        $this->set(compact('menus', 'footerMenus'));
    }


}
