<?php

namespace EventEspresso\core\services\request\sanitizers;

use EventEspresso\core\domain\services\validation\email\strategies\Basic;
use EventEspresso\core\services\request\DataType;

class RequestSanitizer
{
    private Basic $email_validator;


    /**
     * @param Basic $email_validator
     */
    public function __construct(Basic $email_validator)
    {
        $this->email_validator = $email_validator;
    }


    /**
     * Will sanitize the supplied request parameter based on the specified data type
     *
     * @param mixed  $param     the supplied request parameter
     * @param string $type      the specified data type (default: "string")
     *                          valid values: "bool", "float", "int", "key", "url", or "string"
     * @param bool   $is_array  if true, then $param will be treated as an array of $type
     * @param string $delimiter if $param is a CSV like value (ex: 1,2,3,4,5...) then this is the value separator
     * @return array|bool|float|int|string
     * @since 4.10.14.p
     */
    public function clean(
        $param,
        string $type = DataType::STRING,
        bool $is_array = false,
        string $delimiter = ''
    ) {
        if ($delimiter !== '' && is_string($param)) {
            // remove delimiter from end of lists like '1,2,3,4,' to prevent extra elements
            $param    = rtrim($param, $delimiter);
            $param    = explode($delimiter, $param);
            $is_array = is_array($param);
            // unset the delimiter else this function will recurse forever when we loop over the array of results
            $delimiter = '';
        }
        // check if we are getting an improperly typed array and correct
        $is_array = $is_array && is_array($param);
        if ($is_array) {
            return array_map(
                fn ($value) => $this->clean($value, $type, is_array($value), $delimiter),
                (array) $param
            );
        }
        return $this->sanitizeParam($param, $type);
    }


    /**
     * @param mixed  $param
     * @param string $type
     * @return mixed
     * @since   4.10.20.p
     */
    public function sanitizeParam($param, string $type = DataType::STRING)
    {
        switch ($type) {
            case DataType::BOOL:
                return filter_var($param, FILTER_VALIDATE_BOOLEAN);
            case DataType::EDITOR:
                if ($param === null) {
                    return '';
                }
                $allowed_tags = AllowedTags::getWithFullTags();
                return wp_kses($param, $allowed_tags);
            case DataType::EMAIL:
                return $this->email_validator->validate($param) ? $param : '';
            case DataType::FLOAT:
                return (float) $param;
            case DataType::FQCN:
                return preg_replace('[^\\\w\d]', '', $param);
            case DataType::HTML:
                $allowed_tags = AllowedTags::getAllowedTags();
                return wp_kses($param, $allowed_tags);
            case DataType::INT:
                return (int) $param;
            case DataType::KEY:
                return sanitize_key($param);
            case DataType::TITLE:
                return sanitize_title($param);
            case DataType::URL:
                return esc_url_raw($param);
            case DataType::STRING:
            default:
                return sanitize_text_field($param);
        }
    }
}
