<?php
namespace DevOwl\RealThumbnailGenerator\lite\editor;

use DevOwl\RealThumbnailGenerator\attachment\Thumbnail;
use WP_Error;

// @codeCoverageIgnoreStart
defined('ABSPATH') or die('No script kiddies please!'); // Avoid direct file request
// @codeCoverageIgnoreEnd

trait Adapter {
    public static $lastIsPdf = false;
    public static $lastFilePathes = [];
    public static $lastAttachmentId = null;

    public $onlyThisSizes;
    public $skipExisting;

    // Documented in IOverrideAdapter
    public function overrideConstruct() {
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- array elements sanitized via array_map below.
        $rawSizes = isset($_REQUEST['onlyThisSizes']) ? wp_unslash($_REQUEST['onlyThisSizes']) : [];
        $this->onlyThisSizes = is_array($rawSizes) ? array_map('sanitize_text_field', $rawSizes) : [];
        $this->skipExisting = isset($_REQUEST['skipExisting'])
            ? filter_var(wp_unslash($_REQUEST['skipExisting']), FILTER_VALIDATE_BOOLEAN)
            : false;
    }

    // Documented in IOverrideAdapter
    public function checkResize($max_w, $max_h, $crop) {
        $this->doResizeForThisThumbnail = true;
        $imageSize = false;

        if (isset($this->check) && is_array($this->check)) {
            // Only allow "only this thumbnails" when they are given and we do not use a new schema
            if (count($this->onlyThisSizes) > 0 && !$this->isForceNew) {
                $imageSize = $this->rtgThumbnail->get_image_sizes_by($max_w, $max_h, $crop);
                if ($imageSize && !in_array($imageSize[0], $this->onlyThisSizes, true)) {
                    // There is identifier found, please do not resize
                    if (isset($this->check['available'][$imageSize[0]])) {
                        $this->doResizeForThisThumbnail = $this->check['available'][$imageSize[0]];
                        return $this->doResizeForThisThumbnail;
                    } else {
                        return new WP_Error(
                            'image_resize_skip_unused',
                            __('Image resizing failed.', 'real-thumbnail-generator-lite'),
                            $this->file
                        );
                    }
                }
            }

            // Skip files with already existing thumbnails
            if ($this->skipExisting && !$this->isForceNew) {
                if (!$imageSize) {
                    $imageSize = $this->rtgThumbnail->get_image_sizes_by($max_w, $max_h, $crop);
                }

                if ($imageSize && isset($this->check['available'][$imageSize[0]]) && file_exists($this->file)) {
                    $this->doResizeForThisThumbnail = $this->check['available'][$imageSize[0]];
                    return $this->doResizeForThisThumbnail;
                }
            }
        }

        return $this->doResizeForThisThumbnail;
    }

    // Documented in IOverrideAdapter
    public function generate_filename($size, $dest_path = null, $extension = null) {
        $dir = $this->fileInfo['dirname'];
        $ext = $this->fileInfo['extension'];

        $name = wp_basename($this->file, ".$ext");

        // phpcs:disable Generic.PHP.ForbiddenFunctions
        if (!is_null($dest_path) && ($_dest_path = realpath($dest_path))) {
            // phpcs:enable Generic.PHP.ForbiddenFunctions
            $dir = $_dest_path;
        }

        $rtgThumbnail = Thumbnail::getInstance();
        if ($this->usePdfSizes) {
            $imageSize = $rtgThumbnail->get_pdf_sizes_by($this->max_w, $this->max_h, $this->crop);
        } else {
            $imageSize = $rtgThumbnail->get_image_sizes_by($this->max_w, $this->max_h, $this->crop);
        }

        if (self::$lastIsPdf) {
            // Use "full" pdf size
            $imageSize = ['full'];
        } elseif (!is_array($imageSize) || !isset($imageSize[0])) {
            // There is no identifier found
            return false;
        }

        $sizeIdentifier = $imageSize[0];

        // Determine attachment ID
        $check = $this->rtgEditor->activeRegenerationCheck;
        $id = isset($check) ? $check['id'] : self::$lastAttachmentId;

        // We have collected the data now, let's make the filename
        $data = [
            'id' => $id,
            'size-identifier' => $sizeIdentifier,
            'identifier-width' => $this->max_w > 0 ? $this->max_w : 'auto',
            'identifier-height' => $this->max_h > 0 ? $this->max_h : 'auto',
            'name' => $name,
            'extension' => $ext,
            'image-width' => $size['width'],
            'image-height' => $size['height'],
        ];

        // Generate the thumbnail folder name and file name from the schema
        $this->rtgEditor->data = $data;
        list($schema_folder, $schema_filename) = $this->schemas;

        // Generate the names
        $thumbnailFolder = $this->rtgEditor->generate($schema_folder);
        $thumbnailFile = $this->rtgEditor->generate($schema_filename, false, 'replace_filename');
        $result = trailingslashit($thumbnailFolder) . ltrim($thumbnailFile, '/');
        self::$lastFilePathes[$sizeIdentifier] = $result;

        if (!$this->rtgEditor->isValid($result)) {
            // The folder is not valid
            return false;
        }

        /**
         * The resolved path for a thumbnail size.
         *
         * @param {string} $result The resolved path for the thumbnail file
         * @param {int} $id The attachment id
         * @param {array} $data Size identifier, identifier width, image width
         * @param {array} $check General check data for this attachment
         * @return {string}
         * @hook RTG/Regenerate/Path
         * @since 2.1.7
         */
        $result = apply_filters('RTG/Regenerate/Path', $result, $id, $data, $check);

        // The last path join
        $result = trailingslashit($dir) . ltrim($result, '/');

        /**
         * The resolved absolute path for a thumbnail size.
         *
         * @param {string} $result The resolved path for the thumbnail file
         * @param {int} $id The attachment id
         * @param {array} $data Size identifier, identifier width, image width
         * @param {array} $check General check data for this attachment
         * @return {string}
         * @hook RTG/Regenerate/AbsolutePath
         * @since 2.1.7
         */
        $result = apply_filters('RTG/Regenerate/AbsolutePath', $result, $id, $data, $check);
        return $result;
    }
}
