<?php

final class ExtensionStoreRelease
  extends ExtensionStoreDAO
  implements
    PhabricatorPolicyInterface,
    PhabricatorApplicationTransactionInterface,
    PhabricatorDestructibleInterface,
    PhabricatorConduitResultInterface {

  protected $name;
  protected $extensionPHID;
  protected $status = 'active';
  protected $details = array();

  private $extension = self::ATTACHABLE;

  public static function initializeNewRelease(PhabricatorUser $actor) {
    return new self();
  }

  protected function getConfiguration() {
    return array(
      self::CONFIG_AUX_PHID => true,
      self::CONFIG_SERIALIZATION => array(
        'details' => self::SERIALIZATION_JSON,
      ),
      self::CONFIG_COLUMN_SCHEMA => array(
        'name' => 'sort64',
        'status' => 'text32',
      ),
      self::CONFIG_KEY_SCHEMA => array(
        'key_extension' => array(
          'columns' => array('extensionPHID', 'name'),
          'unique' => true,
        ),
      ),
    ) + parent::getConfiguration();
  }

  public function generatePHID() {
    return PhabricatorPHID::generateNewPHID(
      ExtensionStoreReleasePHIDType::TYPECONST);
  }

  public function getURI() {
    if ($this->extension === self::ATTACHABLE) {
      return '';
    }
    $extension = $this->getExtension();
    // Releases don't yet have an actual view controller.
    return $extension->getURI();
  }

  public function attachExtension(ExtensionStoreExtension $extension) {
    $this->extension = $extension;
    $this->extensionPHID = $extension->getPHID();
    return $this;
  }

  /** @return ExtensionStoreExtension */
  public function getExtension() {
    return $this->assertAttached($this->extension);
  }

  public function setDetail($key, $value) {
    $this->details[$key] = $value;
    return $this;
  }

  public function getDetail($key) {
    return idx($this->details, $key);
  }

  public function getDownloadFilePHID() {
   return $this->getDetail('file-phid');
  }

/* -(  PhabricatorSubscribableInterface  )----------------------------------- */


  public function isAutomaticallySubscribed($phid) {
    return false;
  }


/* -(  Policy Interface  )--------------------------------------------------- */


  public function getCapabilities() {
    return array(
      PhabricatorPolicyCapability::CAN_VIEW,
      PhabricatorPolicyCapability::CAN_EDIT,
    );
  }

  public function getPolicy($capability) {
    switch ($capability) {
      case PhabricatorPolicyCapability::CAN_VIEW:
        return PhabricatorPolicies::getMostOpenPolicy();
      case PhabricatorPolicyCapability::CAN_EDIT:
        return PhabricatorPolicies::POLICY_USER;
    }
  }

  public function hasAutomaticCapability($capability, PhabricatorUser $user) {
    return false;
  }


/* -(  PhabricatorDestructibleInterface  )----------------------------------- */


  public function destroyObjectPermanently(
    PhabricatorDestructionEngine $engine) {
    $this->delete();
  }


/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */


  public function getApplicationTransactionEditor() {
    return new ExtensionStoreReleaseTransactionEditor();
  }

  public function getApplicationTransactionTemplate() {
    return new ExtensionStoreReleaseTransaction();
  }

/* -(  PhabricatorConduitResultInterface  )---------------------------------- */


  public function getFieldSpecificationsForConduit() {
    return array(
      id(new PhabricatorConduitSearchFieldSpecification())
        ->setKey('name')
        ->setType('string')
        ->setDescription(pht('The name (number) of the release.')),
    );
  }

  public function getFieldValuesForConduit() {
    return array(
      'name' => $this->getName(),
    );
  }

  public function getConduitSearchAttachments() {
    return array();
  }


}
