<?php

/**
 * Хелпер для роботи з YAML
 * Методи для парсингу та генерації YAML
 *
 * @package Flowaxy\Support\Helpers
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Support\Helpers;

final class YamlHelper
{
    /**
     * Парсити YAML рядок
     *
     * @param string $yaml
     * @param int $flags
     * @return mixed
     */
    public static function parse(string $yaml, int $flags = 0): mixed
    {
        if (!function_exists('yaml_parse')) {
            throw new \RuntimeException('YAML extension is not installed. Install yaml extension or use symfony/yaml package.');
        }

        return yaml_parse($yaml, $flags);
    }

    /**
     * Генерувати YAML з даних
     *
     * @param mixed $data
     * @param int $indent
     * @param int $flags
     * @return string|false
     */
    public static function dump(mixed $data, int $indent = 2, int $flags = 0): string|false
    {
        if (!function_exists('yaml_emit')) {
            throw new \RuntimeException('YAML extension is not installed. Install yaml extension or use symfony/yaml package.');
        }

        return yaml_emit($data, $flags, $indent);
    }

    /**
     * Прочитати YAML з файлу
     *
     * @param string $path
     * @param int $flags
     * @return mixed|false
     */
    public static function readFile(string $path, int $flags = 0): mixed
    {
        if (!FileHelper::exists($path)) {
            return false;
        }

        $content = FileHelper::get($path);
        if ($content === false) {
            return false;
        }

        return self::parse($content, $flags);
    }

    /**
     * Записати YAML у файл
     *
     * @param string $path
     * @param mixed $data
     * @param int $indent
     * @param int $flags
     * @return bool
     */
    public static function writeFile(string $path, mixed $data, int $indent = 2, int $flags = 0): bool
    {
        $yaml = self::dump($data, $indent, $flags);
        if ($yaml === false) {
            return false;
        }

        return FileHelper::put($path, $yaml) !== false;
    }

    /**
     * Перевірити, чи рядок є валідним YAML
     *
     * @param string $yaml
     * @return bool
     */
    public static function isValid(string $yaml): bool
    {
        try {
            $result = self::parse($yaml);

            return $result !== false;
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * Валідувати YAML файл
     *
     * @param string $path
     * @return bool
     */
    public static function validate(string $path): bool
    {
        if (!FileHelper::exists($path)) {
            return false;
        }

        $content = FileHelper::get($path);
        if ($content === false) {
            return false;
        }

        return self::isValid($content);
    }

    /**
     * Об'єднати YAML дані
     *
     * @param mixed ...$data
     * @return array<string, mixed>|false
     */
    public static function merge(mixed ...$data): array|false
    {
        $result = [];

        foreach ($data as $item) {
            if (is_string($item)) {
                $item = self::parse($item);
                if ($item === false) {
                    return false;
                }
            }

            if (is_array($item)) {
                $result = array_merge_recursive($result, $item);
            } else {
                return false;
            }
        }

        return $result;
    }
}
