<?php

final class ExtensionStoreReleaseExtensionTransaction
  extends ExtensionStoreReleaseTransactionType {

  const TRANSACTIONTYPE = 'est:release:extension';

  public function generateOldValue($object) {
    return $object->getExtensionPHID();
  }

  // TODO add respective xaction on Exception object.

  public function applyInternalEffects($object, $value) {
    $object->setExtensionPHID($value);
  }

  public function validateTransactions($object, array $xactions) {
    $errors = array();

    if ($this->isEmptyTextTransaction($object->getExtensionPHID(), $xactions)) {
      $errors[] = $this->newRequiredError(
        pht(
          'You must select a extension when creating a release'));
      return $errors;
    }

    if (!$this->isNewObject()) {
      foreach ($xactions as $xaction) {
        $errors[] = $this->newInvalidError(
          pht('Once a release is created, its extension can not be changed.'),
          $xaction);
      }
    }

    $viewer = $this->getActor();
    foreach ($xactions as $xaction) {
      $extension_phid = $xaction->getNewValue();

      $extension = id(new ExtensionStoreExtensionQuery())
        ->setViewer($viewer)
        ->withPHIDs(array($extension_phid))
        ->setRaisePolicyExceptions(false)
        ->requireCapabilities(
          array(
            PhabricatorPolicyCapability::CAN_VIEW,
            PhabricatorPolicyCapability::CAN_EDIT,
          ))
        ->executeOne();

      if (!$extension) {
        $errors[] = $this->newInvalidError(
          pht(
            'Extension "%s" is invalid: the extension must exist and you '.
            'must have permission to edit it in order to create a new '.
            'release.',
            $extension_phid),
          $xaction);
        continue;
      }

      $object->attachExtension($extension);
    }

    return $errors;
  }

}
