<?php

declare(strict_types=1);

namespace Enot;

// Avoid direct access to this piece of code
defined('ABSPATH') || exit;

use Throwable;

abstract class EnotNotifier
{
	protected static Throwable $e;

	abstract protected static function format(): string;
	abstract public static function notify(Throwable $e): bool;

	protected static function severityName(int $severity): string
	{
		if (Enot::isInFatal($severity)) {
			// Get an Exception type, or return 'Fatal error'
			return $severity === -1 ? get_class(self::$e) : 'Fatal error';
		}

		// Is it an E_* error?
		if (array_key_exists($severity, Enot::errorLevels())) {
			return Enot::errorLevels()[$severity]['name'];
		}

		return 'UNKNOWN';
	}

	protected static function getRequestIp(): string
	{
		if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
			$ip = \sanitize_text_field(\wp_unslash($_SERVER['HTTP_CLIENT_IP']));
		} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
			$http_x_forwarded_for = \sanitize_text_field(\wp_unslash($_SERVER['HTTP_X_FORWARDED_FOR']));

			/** @var string|false */
			$first_ip = strstr($http_x_forwarded_for, ',', true);

			$ip = $first_ip ?: $http_x_forwarded_for;
		} else {
			$ip = !empty($_SERVER['REMOTE_ADDR']) ? \sanitize_text_field(\wp_unslash($_SERVER['REMOTE_ADDR'])) : '';
		}

		return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : 'Unknown';
	}

	protected static function isNotificationEnabled(int $severity): bool
	{
		if (in_array($severity, Enot::$config['severities'], true)) {
			return true;
		}

		return false;
	}

	protected static function urlReplaceSensitiveArgs(string $url): string
	{
		if (\apply_filters('enot_ignore_url_replace_sensitive_args', false)) {
			return $url;
		}

		$sensitivities = \apply_filters('enot_url_replace_sensitive_args', [
			'token',
			'api_key',
			'key',
			'oauth_token',
			'password',
			'secret',
			'access_token',
			'refresh_token',
			'auth_token',
			'session_id',
			'client_secret',
			'private_key',
			'public_key',
			'encryption_key',
			'jwt',
			'bearer_token',
			'passphrase',
			'db_password',
			'connection_string',
		]);

		$parsed = \wp_parse_url($url);

		if (!isset($parsed['query'])) {
			return $url;
		}

		parse_str($parsed['query'], $query);

		array_walk($query, function (&$value, $key, $sensitivities) {
			if (in_array(strtolower($key), $sensitivities, true)) {
				$value = str_repeat('x', strlen($value));
			}
		}, $sensitivities);

		$url = '';

		if (isset($parsed['scheme'])) {
			$url .= $parsed['scheme'] . '://';
		}

		if (isset($parsed['host'])) {
			$url .= $parsed['host'];
		}

		if (isset($parsed['path'])) {
			$url .= $parsed['path'];
		}

		if (!empty($query)) {
			$url .= '?' . http_build_query($query);

			if (substr($parsed['query'], -1) === '/') {
				$url .= '/';
			}
		}

		if (isset($parsed['fragment'])) {
			$url .= '#' . $parsed['fragment'];
		}

		return \apply_filters('enot_url_after_sensitive_replacement', $url);
	}
}
