<?php

declare(strict_types=1);

namespace Drupal\Tests\flowdrop_memory\Unit\Exception;

use Drupal\flowdrop_memory\Exception\MemoryBackendException;
use Drupal\flowdrop_memory\Exception\MemoryKeyNotFoundException;
use Drupal\Tests\UnitTestCase;

/**
 * Tests the flowdrop_memory exception classes.
 *
 * @group flowdrop_memory
 */
class ExceptionTest extends UnitTestCase {

  /**
   * @covers \Drupal\flowdrop_memory\Exception\MemoryBackendException
   */
  public function testMemoryBackendExceptionExtendsRuntimeException(): void {
    $exception = new MemoryBackendException('test error');
    $this->assertInstanceOf(\RuntimeException::class, $exception);
  }

  /**
   * @covers \Drupal\flowdrop_memory\Exception\MemoryBackendException
   */
  public function testMemoryBackendExceptionPreservesMessage(): void {
    $exception = new MemoryBackendException('something went wrong');
    $this->assertSame('something went wrong', $exception->getMessage());
  }

  /**
   * @covers \Drupal\flowdrop_memory\Exception\MemoryKeyNotFoundException
   */
  public function testMemoryKeyNotFoundExceptionExtendsBackendException(): void {
    $exception = new MemoryKeyNotFoundException('global', '', 'missing_key');
    $this->assertInstanceOf(MemoryBackendException::class, $exception);
  }

  /**
   * @covers \Drupal\flowdrop_memory\Exception\MemoryKeyNotFoundException
   */
  public function testMemoryKeyNotFoundExceptionExtendsRuntimeException(): void {
    $exception = new MemoryKeyNotFoundException('global', '', 'missing_key');
    $this->assertInstanceOf(\RuntimeException::class, $exception);
  }

  /**
   * @covers \Drupal\flowdrop_memory\Exception\MemoryKeyNotFoundException
   */
  public function testMemoryKeyNotFoundExceptionMessageContainsKey(): void {
    $exception = new MemoryKeyNotFoundException('global', '', 'my_missing_key');
    $this->assertStringContainsString('my_missing_key', $exception->getMessage());
  }

  /**
   * @covers \Drupal\flowdrop_memory\Exception\MemoryKeyNotFoundException
   */
  public function testMemoryKeyNotFoundExceptionMessageContainsScope(): void {
    $exception = new MemoryKeyNotFoundException('workflow', 'wf-123', 'key');
    $this->assertStringContainsString('workflow', $exception->getMessage());
  }

  /**
   * @covers \Drupal\flowdrop_memory\Exception\MemoryKeyNotFoundException
   */
  public function testMemoryKeyNotFoundExceptionMessageContainsScopeId(): void {
    $exception = new MemoryKeyNotFoundException('workflow', 'wf-123', 'key');
    $this->assertStringContainsString('wf-123', $exception->getMessage());
  }

  /**
   * @covers \Drupal\flowdrop_memory\Exception\MemoryKeyNotFoundException
   */
  public function testMemoryKeyNotFoundExceptionFormatsMessageCorrectly(): void {
    $exception = new MemoryKeyNotFoundException('pipeline', 'pl-456', 'counter');
    $expected = "Memory key 'counter' not found in scope 'pipeline' (scope_id: 'pl-456').";
    $this->assertSame($expected, $exception->getMessage());
  }

  /**
   * @covers \Drupal\flowdrop_memory\Exception\MemoryKeyNotFoundException
   */
  public function testMemoryKeyNotFoundExceptionWithEmptyScopeId(): void {
    $exception = new MemoryKeyNotFoundException('global', '', 'my_key');
    $expected = "Memory key 'my_key' not found in scope 'global' (scope_id: '').";
    $this->assertSame($expected, $exception->getMessage());
  }

}
