<?php

declare(strict_types=1);

namespace Drupal\Tests\flowdrop_node_processor\Unit\Plugin\FlowDropNodeProcessor;

use Drupal\flowdrop\DTO\ParameterBag;
use Drupal\flowdrop_node_processor\Plugin\FlowDropNodeProcessor\TextProcessor;
use PHPUnit\Framework\TestCase;

/**
 * Tests the TextProcessor node processor.
 *
 * @coversDefaultClass \Drupal\flowdrop_node_processor\Plugin\FlowDropNodeProcessor\TextProcessor
 * @group flowdrop_node_processor
 */
class TextProcessorTest extends TestCase {

  /**
   * Creates a TextProcessor instance.
   */
  private function createProcessor(): TextProcessor {
    return new TextProcessor([], 'text_processor', ['id' => 'text_processor']);
  }

  /**
   * @covers ::process
   */
  public function testCapitalize(): void {
    $result = $this->createProcessor()->process(new ParameterBag([
      'text' => 'hello world',
      'operation' => 'capitalize',
    ]));

    $this->assertSame('Hello World', $result['text']);
  }

  /**
   * @covers ::process
   */
  public function testUppercase(): void {
    $result = $this->createProcessor()->process(new ParameterBag([
      'text' => 'Hello World',
      'operation' => 'uppercase',
    ]));

    $this->assertSame('HELLO WORLD', $result['text']);
  }

  /**
   * @covers ::process
   */
  public function testLowercase(): void {
    $result = $this->createProcessor()->process(new ParameterBag([
      'text' => 'Hello World',
      'operation' => 'lowercase',
    ]));

    $this->assertSame('hello world', $result['text']);
  }

  /**
   * @covers ::process
   */
  public function testTrim(): void {
    $result = $this->createProcessor()->process(new ParameterBag([
      'text' => "  hello\t\n",
      'operation' => 'trim',
    ]));

    $this->assertSame('hello', $result['text']);
  }

  /**
   * @covers ::process
   */
  public function testStripTags(): void {
    $result = $this->createProcessor()->process(new ParameterBag([
      'text' => '<p>Hello <strong>World</strong></p>',
      'operation' => 'strip_tags',
    ]));

    $this->assertSame('Hello World', $result['text']);
  }

  /**
   * Default operation is capitalize when none is supplied.
   *
   * @covers ::process
   */
  public function testDefaultOperationIsCapitalize(): void {
    $result = $this->createProcessor()->process(new ParameterBag([
      'text' => 'hello world',
    ]));

    $this->assertSame('Hello World', $result['text']);
  }

  /**
   * Unknown operations fall back to the default.
   *
   * @covers ::process
   */
  public function testUnknownOperationFallsBackToDefault(): void {
    $result = $this->createProcessor()->process(new ParameterBag([
      'text' => 'hello world',
      'operation' => 'reverse',
    ]));

    $this->assertSame('Hello World', $result['text']);
  }

  /**
   * @covers ::process
   */
  public function testEmptyInput(): void {
    $result = $this->createProcessor()->process(new ParameterBag([
      'text' => '',
      'operation' => 'uppercase',
    ]));

    $this->assertSame('', $result['text']);
  }

  /**
   * Non-ASCII input is handled with multibyte-safe transforms.
   *
   * @covers ::process
   */
  public function testMultibyteSafeUppercase(): void {
    $result = $this->createProcessor()->process(new ParameterBag([
      'text' => 'café',
      'operation' => 'uppercase',
    ]));

    $this->assertSame('CAFÉ', $result['text']);
  }

  /**
   * @covers ::process
   */
  public function testMultibyteSafeCapitalize(): void {
    $result = $this->createProcessor()->process(new ParameterBag([
      'text' => 'über alles',
      'operation' => 'capitalize',
    ]));

    $this->assertSame('Über Alles', $result['text']);
  }

}
