<?php

final class ExtensionStoreExtensionSearchEngine
  extends PhabricatorApplicationSearchEngine {

  private ?ExtensionStorePublisher $publisher = null;

  public function setPublisher(ExtensionStorePublisher $publisher) {
    $this->publisher = $publisher;
    return $this;
  }

  public function getPublisher() {
    return $this->publisher;
  }

  public function getResultTypeDescription() {
    return pht('Extensions');
  }

  public function newQuery() {
    $query = id(new ExtensionStoreExtensionQuery());
    if ($this->getPublisher()) {
      $query->withPublisher($this->getPublisher());
    }
    return $query;
  }

  protected function buildCustomSearchFields() {
    $fields = array();

    if ($this->getPublisher()) {
      $fields[] = id(new PhorgeStaticSearchField())
        ->setKey('publisherPHID')
        ->setLabel(pht('Publisher'))
        ->setValue($this->getPublisher()->getPHID())
        ->setRenderValue($this->getPublisher()->getName());
    } else {
      $fields[] = new PhabricatorPHIDsSearchField()
        ->setKey('publisherPHID')
        ->setLabel(pht('Publisher'));
    }


    return $fields;
  }

  protected function getURI($path) {
    if ($this->getPublisher()) {
      return "extensionstore/publisher/{$this->getPublisher()->getID()}/{$path}";
    }
    return "/extensionstore/extension/{$path}";
  }

  protected function getBuiltinQueryNames() {
    $names = array();

    $names['all'] = pht('All Extensions');
    // active?
    // mine
    // phorge
    // arcanist


    return $names;
  }

  public function buildSavedQueryFromBuiltin($query_key) {
    $query = $this->newSavedQuery();
    $query->setQueryKey($query_key);

    switch ($query_key) {
      case 'all':
        return $query;
      // case 'open':
      //   return $query->setParameter(
      //     'statuses',
      //     array(
      //       ExtensionStorePublisher::STATUS_ACTIVE,
      //     ))
          ;
    }

    return parent::buildSavedQueryFromBuiltin($query_key);
  }

  protected function buildQueryFromParameters(array $map) {
    $query = $this->newQuery();

    // TODO type id/phid

    if ($map['publisherPHID']) {
      $query->withPublisherPHIDs($map['publisherPHID']);
    }

    // if ($map['editable'] !== null) {
    //   $query->withCanEdit($map['editable']);
    // }

    return $query;
  }

  protected function getRequiredHandlePHIDsForResultList(
    array $objects,
    PhabricatorSavedQuery $query) {

    return array();
  }

  public function renderResultsDirectly(array $items) {
    return $this->renderResultList(
      $items,
      new PhabricatorSavedQuery(),
      array());
  }

  protected function renderResultList(
    array $items,
    PhabricatorSavedQuery $query ,
    array $handles) {

    $viewer = $this->requireViewer();

    if ($items) {
      $edge_query = id(new PhabricatorEdgeQuery())
        ->withSourcePHIDs(mpull($items, 'getPHID'))
        ->withEdgeTypes(
          array(
            PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
          ));

      // $edge_query->execute();
    }

    $list = id(new PHUIObjectItemListView())
      ->setViewer($viewer);

    foreach ($items as $extension) {
      $item = id(new PHUIObjectItemView())
        ->setViewer($viewer)
        ->setHeader($extension->getName())
        ->setHref($extension->getURI())
        ->setObject($extension);

      $item->setEpoch($extension->getDateModified()); // TODO last published


/// TODO FLAGS

      $can_edit = PhabricatorPolicyFilter::hasCapability(
        $viewer,
        $extension,
        PhabricatorPolicyCapability::CAN_EDIT);

      $list->addItem($item);
    }

    $result = new PhabricatorApplicationSearchResultView();
    $result->setObjectList($list);
    $result->setNoDataString(pht('No extensions found.'));

    return $result;
  }

/* -(  Export   )------------------------------------------------------------ */

  protected function newExportFields() {
    return array(
      id(new PhabricatorStringExportField())
        ->setKey('name')
        ->setLabel(pht('Name')),
      id(new PhabricatorStringExportField())
        ->setKey('description')
        ->setLabel(pht('Description')),
      id(new PhabricatorStringExportField())
        ->setKey('rawData')
        ->setLabel(pht('Raw Data')),
      id(new PhabricatorPHIDExportField())
        ->setKey('publisherPHID')
        ->setLabel(pht('Class PHID')),
      id(new PhabricatorURIExportField())
        ->setKey('uri')
        ->setLabel(pht('URI')),
    );
  }

  protected function newExportData(array $extensions) {
    $export = array();
    foreach ($extensions as $extension) {

      $export[] = array(
        'name' => $extension->getName(),
        'uri' => PhabricatorEnv::getProductionURI($extension->getURI()),
        'description' => $extension->getDescription(),
        'publisherPHID' => $extension->getPublisherPHID(),
        'rawData' => $extension->getRawData(),
      );
    }

    return $export;
  }

  public function getApplicationClassName() {
    return ExtensionsStoreApplication::class;
  }


}
