<?php

namespace App\Libraries;

use App\Libraries\OperationContext;
use App\Services\MylogService;
use RuntimeException;

class PipelineStep
{
  protected MylogService $logService;

  // CI4의 DI (의존성 주입)를 통해 LogService만 받습니다.
  public function __construct(MylogService $logService)
  {
    $this->logService = $logService;
  }

  /**
   * 서비스 단계(Step) 배열을 받아 순차적으로 실행합니다.
   * @param array<PipelineStep> $steps 실행할 PipelineStep 객체들의 배열
   * @param OperationContext $context 초기 컨텍스트
   * @return OperationContext 최종 컨텍스트
   */
  public function run(array $steps, OperationContext $context): OperationContext
  {
    $db = \Config\Database::connect();
    $db->transBegin();
    try {
      // 1. Log START: 파이프라인 시작 로깅
      $this->logService->log($context, 'START');
      // 2. 단계(Steps) 순차 실행
      foreach ($steps as $step) {
        if (!($step instanceof PipelineStepInterface)) {
          throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 파이프라인 단계는 PipelineStep 인터페이스를 구현해야 합니다.");
        }
        $context = $step->handle($context);
      }
      // 3. Log SUCCESS: 모든 단계 성공 로깅
      $this->logService->log($context, 'SUCCESS');
      return $context;
    } catch (\Throwable $e) {
      $db->transRollback();
      // 4. Log FAILURE: 오류 발생 시 즉시 로깅
      $context->error = $e;
      $this->logService->log($context, 'FAILURE');
      // 5. 오류를 상위 계층으로 전파
      throw $e;
    }
  }
}
