<?php

namespace App\Services;

use App\Data\Validation\ValidatesArray;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class CorsService
{
    private const CONFIG_KEY = 'cors';
    private const CONFIG_PATH_REGEX_DELIMITER = '~';

    private ValidatesArray $configValidator;

    /**
     * @var mixed[]
     */
    private array $config;

    /**
     * @param ValidatesArray $configValidator
     */
    public function __construct(ValidatesArray $configValidator)
    {
        $this->configValidator = $configValidator;
        $this->config = $this->determineConfig();
    }

    private function determineConfig(): array
    {
        $config = config(self::CONFIG_KEY, []);
        $this->configValidator->validateArray($config)->assertIsSuccess();

        if (empty($config['origin'])) {
            $config['origin'] = '*';
        }

        $config['path'] = sprintf(
            '%2$s%1$s%2$s',
            $config['path'],
            self::CONFIG_PATH_REGEX_DELIMITER,
        );

        return $config;
    }

    public function isRequestValid(Request $request): bool
    {
        return 1 === preg_match($this->config['path'], $request->getPathInfo());
    }

    public function addHeadersToResponse(Response $response): void
    {
        $this->addHeaderToResponseByArray(
            'Access-Control-Allow-Methods',
            $this->config['methods'],
            $response,
        );

        $this->addHeaderToResponseByArray(
            'Access-Control-Allow-Headers',
            $this->config['headers'],
            $response,
        );

        $response->header(
            'Access-Control-Allow-Origin',
            $this->config['origin'],
        );
    }

    private function addHeaderToResponseByArray(string $key, array $values, Response $response): void
    {
        $response->header($key, implode(', ', $values));
    }
}
