<?php

declare(strict_types=1);

namespace Drupal\Tests\flowdrop_workflow_executor\Unit\DTO;

use Drupal\Tests\UnitTestCase;
use Drupal\flowdrop_workflow_executor\DTO\WorkflowExecutionResult;
use Drupal\flowdrop_workflow_executor\Enum\WorkflowExecutionStatus;

/**
 * Tests the WorkflowExecutionResult DTO.
 *
 * @coversDefaultClass \Drupal\flowdrop_workflow_executor\DTO\WorkflowExecutionResult
 * @group flowdrop_workflow_executor
 */
class WorkflowExecutionResultTest extends UnitTestCase {

  /**
   * @covers ::success
   * @covers ::isSuccess
   * @covers ::getStatus
   */
  public function testSuccess(): void {
    $result = WorkflowExecutionResult::success(
      sessionId: "sess_1",
      outputs: ["result" => "done"],
      executionTimeMs: 150,
      jobId: "job_1",
    );
    $this->assertTrue($result->isSuccess());
    $this->assertSame(WorkflowExecutionStatus::Completed, $result->getStatus());
    $this->assertEquals("sess_1", $result->getSessionId());
    $this->assertEquals("job_1", $result->getJobId());
    $this->assertEquals(["result" => "done"], $result->getOutputs());
    $this->assertEquals(150, $result->getExecutionTimeMs());
    $this->assertEquals("", $result->getErrorMessage());
  }

  /**
   * @covers ::pending
   */
  public function testPending(): void {
    $result = WorkflowExecutionResult::pending("sess_2", "job_2");
    $this->assertTrue($result->isSuccess());
    $this->assertSame(WorkflowExecutionStatus::Pending, $result->getStatus());
    $this->assertEquals("sess_2", $result->getSessionId());
  }

  /**
   * @covers ::running
   */
  public function testRunning(): void {
    $result = WorkflowExecutionResult::running("sess_3", "job_3");
    $this->assertTrue($result->isSuccess());
    $this->assertSame(WorkflowExecutionStatus::Running, $result->getStatus());
  }

  /**
   * @covers ::failure
   */
  public function testFailure(): void {
    $result = WorkflowExecutionResult::failure("Something went wrong", "sess_4");
    $this->assertFalse($result->isSuccess());
    $this->assertSame(WorkflowExecutionStatus::Failed, $result->getStatus());
    $this->assertEquals("Something went wrong", $result->getErrorMessage());
    $this->assertEquals("sess_4", $result->getSessionId());
  }

  /**
   * @covers ::timeout
   */
  public function testTimeout(): void {
    $result = WorkflowExecutionResult::timeout("sess_5", 30000);
    $this->assertFalse($result->isSuccess());
    $this->assertSame(WorkflowExecutionStatus::Timeout, $result->getStatus());
    $this->assertEquals("Workflow execution timed out", $result->getErrorMessage());
    $this->assertEquals(30000, $result->getExecutionTimeMs());
  }

  /**
   * @covers ::toArray
   */
  public function testToArray(): void {
    $result = WorkflowExecutionResult::success("sess_6", ["key" => "val"], 200, "job_6");
    $array = $result->toArray();

    $this->assertTrue($array["success"]);
    $this->assertEquals("completed", $array["status"]);
    $this->assertEquals("sess_6", $array["session_id"]);
    $this->assertEquals("job_6", $array["job_id"]);
    $this->assertEquals(["key" => "val"], $array["outputs"]);
    $this->assertEquals("", $array["error_message"]);
    $this->assertEquals(200, $array["execution_time_ms"]);
  }

}
