<?php

namespace Drupal\eb\Service;

use Drupal\eb\Exception\ValidationException;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;

/**
 * Service for YAML parsing and export operations.
 *
 * This service provides direct YAML parsing capabilities without the overhead
 * of a plugin system. It handles parsing, exporting, and validation of YAML
 * content for entity architecture definitions.
 */
class YamlParser {

  /**
   * Parse YAML content into an array.
   *
   * @param string $content
   *   The YAML content to parse.
   *
   * @return array<string, mixed>
   *   The parsed data as an associative array.
   *
   * @throws \Drupal\eb\Exception\ValidationException
   *   If the content is empty or invalid YAML.
   */
  public function parse(string $content): array {
    $trimmedContent = trim($content);

    if ($trimmedContent === '') {
      throw new ValidationException('YAML content is empty');
    }

    try {
      $data = Yaml::parse($content);

      if (!is_array($data)) {
        throw new ValidationException('YAML content must be an array');
      }

      return $data;
    }
    catch (ParseException $e) {
      throw new ValidationException(
        'YAML parsing error: ' . $e->getMessage(),
        [],
        0,
        $e
      );
    }
  }

  /**
   * Export data to YAML string.
   *
   * @param array<mixed> $data
   *   The data to export.
   *
   * @return string
   *   The YAML string representation.
   */
  public function export(array $data): string {
    return Yaml::dump($data, 4, 2);
  }

  /**
   * Validate that a file path has a YAML extension.
   *
   * @param string $filePath
   *   The file path to validate.
   *
   * @return bool
   *   TRUE if the file has a valid YAML extension.
   */
  public function validateExtension(string $filePath): bool {
    $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
    return in_array($extension, ['yml', 'yaml'], TRUE);
  }

  /**
   * Validate that content is valid YAML syntax.
   *
   * This method checks if content can be parsed as YAML without throwing
   * exceptions. Use this for validation checks where you don't need the
   * parsed data.
   *
   * @param string $content
   *   The content to validate.
   *
   * @return bool
   *   TRUE if the content is valid YAML, FALSE otherwise.
   */
  public function validateContent(string $content): bool {
    $trimmedContent = trim($content);

    if ($trimmedContent === '') {
      return FALSE;
    }

    try {
      $data = Yaml::parse($content);
      return is_array($data);
    }
    catch (ParseException $e) {
      return FALSE;
    }
  }

  /**
   * Get the supported file extensions.
   *
   * @return array<int, string>
   *   Array of supported file extensions (without dots).
   */
  public function getFileExtensions(): array {
    return ['yml', 'yaml'];
  }

}
