<?php

final class SemiStructuredObjectInstanceViewController
  extends SemiStructuredObjectInstanceController {

  public function handleRequest(AphrontRequest $request) {
    $viewer = $request->getViewer();
    $id = $request->getURIData('id');

    $object = id(new SemiStructuredObjectInstanceQuery())
      ->setViewer($viewer)
      ->withIDs(array($id))
      ->executeOne();
    if (!$object) {
      return new Aphront404Response();
    }

    $this->setObject($object);
    $object_type = $object->getClass();

    $crumbs = $this->buildApplicationCrumbs();
    $title = pht(
      '%s: %d %s',
      $object_type->getName(),
      $object->getID(),
      $object->getName());

    $header = $this->buildHeaderView();
    $curtain = $this->buildCurtain();
    $details = $this->buildDetailsView();

    $timeline = $this->buildTransactionTimeline(
      $object,
      new SemiStructuredObjectInstanceTransactionQuery());

    $comment_view = id(new SemiStructuredObjectInstanceEditEngine())
      ->setViewer($viewer)
      ->buildEditEngineCommentView($object);

    $view = id(new PHUITwoColumnView())
      ->setHeader($header)
      ->setCurtain($curtain)
      ->setMainColumn(array(
          $timeline,
          $comment_view,
        ))
      ->addPropertySection(pht('Details'), $details);

    return $this->newPage()
      ->setTitle($title)
      ->setCrumbs($crumbs)
      ->setPageObjectPHIDs(array($object->getPHID()))
      ->appendChild($view);
  }

private function buildDetailsView() {
    $viewer = $this->getViewer();
    $object = $this->getObject();

    $view = id(new PHUIPropertyListView())
      ->setUser($viewer);

    $description = $object->getDescription();
    if (strlen($description)) {
      $view->addTextContent(
        new PHUIRemarkupView($viewer, $description));
      }

    $field_list = PhabricatorCustomField::getObjectFields(
        $object,
        PhabricatorCustomField::ROLE_VIEW);
      $field_list->appendFieldsToPropertyList($object, $viewer, $view);


    $content = $object->getRawData();
    $content = id(new PhutilJSON())
      ->encodeFormatted(json_decode($content));

    $view->addProperty(
      pht('Structured content'),
      phutil_tag('pre', array(), $content));

    return $view;
  }

  private function buildCurtain() {
    $viewer = $this->getViewer();
    $object = $this->getObject();

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

    $id = $object->getID();
    $edit_uri = $this->getApplicationURI("/editinstance/{$id}/");

    $curtain = $this->newCurtainView($object);

    $curtain->addAction(
      id(new PhabricatorActionView())
        ->setName(pht('Edit Instance'))
        ->setIcon('fa-pencil')
        ->setDisabled(!$can_edit)
        ->setHref($edit_uri));


    return $curtain;
  }

}
