public function execute(PhutilArgumentParser $args)
 {
     $console = PhutilConsole::getConsole();
     $ids = $args->getArg('id');
     if (!$ids) {
         throw new PhutilArgumentUsageException(pht("Use the '%s' flag to specify one or more messages to show.", '--id'));
     }
     $messages = id(new PhabricatorMetaMTAMail())->loadAllWhere('id IN (%Ld)', $ids);
     if ($ids) {
         $ids = array_fuse($ids);
         $missing = array_diff_key($ids, $messages);
         if ($missing) {
             throw new PhutilArgumentUsageException(pht('Some specified messages do not exist: %s', implode(', ', array_keys($missing))));
         }
     }
     $last_key = last_key($messages);
     foreach ($messages as $message_key => $message) {
         if ($args->getArg('dump-html')) {
             $html_body = $message->getHTMLBody();
             if (strlen($html_body)) {
                 $template = "<!doctype html><html><body>{$html_body}</body></html>";
                 $console->writeOut("%s\n", $html_body);
             } else {
                 $console->writeErr("%s\n", pht('(This message has no HTML body.)'));
             }
             continue;
         }
         $info = array();
         $info[] = pht('PROPERTIES');
         $info[] = pht('ID: %d', $message->getID());
         $info[] = pht('Status: %s', $message->getStatus());
         $info[] = pht('Related PHID: %s', $message->getRelatedPHID());
         $info[] = pht('Message: %s', $message->getMessage());
         $ignore = array('body' => true, 'html-body' => true, 'headers' => true, 'attachments' => true, 'headers.sent' => true, 'authors.sent' => true);
         $info[] = null;
         $info[] = pht('PARAMETERS');
         $parameters = $message->getParameters();
         foreach ($parameters as $key => $value) {
             if (isset($ignore[$key])) {
                 continue;
             }
             if (!is_scalar($value)) {
                 $value = json_encode($value);
             }
             $info[] = pht('%s: %s', $key, $value);
         }
         $info[] = null;
         $info[] = pht('HEADERS');
         $headers = $message->getDeliveredHeaders();
         if (!$headers) {
             $headers = $message->generateHeaders();
         }
         foreach ($headers as $header) {
             list($name, $value) = $header;
             $info[] = "{$name}: {$value}";
         }
         $attachments = idx($parameters, 'attachments');
         if ($attachments) {
             $info[] = null;
             $info[] = pht('ATTACHMENTS');
             foreach ($attachments as $attachment) {
                 $info[] = idx($attachment, 'filename', pht('Unnamed File'));
             }
         }
         $all_actors = $message->loadAllActors();
         $actors = $message->getDeliveredActors();
         if ($actors) {
             $info[] = null;
             $info[] = pht('RECIPIENTS');
             foreach ($actors as $actor_phid => $actor_info) {
                 $actor = idx($all_actors, $actor_phid);
                 if ($actor) {
                     $actor_name = coalesce($actor->getName(), $actor_phid);
                 } else {
                     $actor_name = $actor_phid;
                 }
                 $deliverable = $actor_info['deliverable'];
                 if ($deliverable) {
                     $info[] = '  ' . $actor_name;
                 } else {
                     $info[] = '! ' . $actor_name;
                 }
                 $reasons = $actor_info['reasons'];
                 foreach ($reasons as $reason) {
                     $name = PhabricatorMetaMTAActor::getReasonName($reason);
                     $desc = PhabricatorMetaMTAActor::getReasonDescription($reason);
                     $info[] = '    - ' . $name . ': ' . $desc;
                 }
             }
         }
         $info[] = null;
         $info[] = pht('TEXT BODY');
         if (strlen($message->getBody())) {
             $info[] = $message->getBody();
         } else {
             $info[] = pht('(This message has no text body.)');
         }
         $info[] = null;
         $info[] = pht('HTML BODY');
         if (strlen($message->getHTMLBody())) {
             $info[] = $message->getHTMLBody();
             $info[] = null;
         } else {
             $info[] = pht('(This message has no HTML body.)');
         }
         $console->writeOut('%s', implode("\n", $info));
         if ($message_key != $last_key) {
             $console->writeOut("\n%s\n\n", str_repeat('-', 80));
         }
     }
 }
 private function buildDeliveryProperties(PhabricatorMetaMTAMail $mail)
 {
     $viewer = $this->getViewer();
     $properties = id(new PHUIPropertyListView())->setUser($viewer);
     $actors = $mail->getDeliveredActors();
     $reasons = null;
     if (!$actors) {
         if ($mail->getStatus() == PhabricatorMailOutboundStatus::STATUS_QUEUE) {
             $delivery = $this->renderEmptyMessage(pht('This message has not been delivered yet, so delivery information ' . 'is not available.'));
         } else {
             $delivery = $this->renderEmptyMessage(pht('This is an older message that predates recording delivery ' . 'information, so none is available.'));
         }
     } else {
         $actor = idx($actors, $viewer->getPHID());
         if (!$actor) {
             $delivery = phutil_tag('em', array(), pht('This message was not delivered to you.'));
         } else {
             $deliverable = $actor['deliverable'];
             if ($deliverable) {
                 $delivery = pht('Delivered');
             } else {
                 $delivery = pht('Voided');
             }
             $reasons = id(new PHUIStatusListView());
             $reason_codes = $actor['reasons'];
             if (!$reason_codes) {
                 $reason_codes = array(PhabricatorMetaMTAActor::REASON_NONE);
             }
             $icon_yes = 'fa-check green';
             $icon_no = 'fa-times red';
             foreach ($reason_codes as $reason) {
                 $target = phutil_tag('strong', array(), PhabricatorMetaMTAActor::getReasonName($reason));
                 if (PhabricatorMetaMTAActor::isDeliveryReason($reason)) {
                     $icon = $icon_yes;
                 } else {
                     $icon = $icon_no;
                 }
                 $item = id(new PHUIStatusItemView())->setIcon($icon)->setTarget($target)->setNote(PhabricatorMetaMTAActor::getReasonDescription($reason));
                 $reasons->addItem($item);
             }
         }
     }
     $properties->addProperty(pht('Delivery'), $delivery);
     if ($reasons) {
         $properties->addProperty(pht('Reasons'), $reasons);
         $properties->addProperty(null, $this->renderEmptyMessage(pht('Delivery reasons are listed from weakest to strongest.')));
     }
     $properties->addSectionHeader(pht('Routing Rules'), 'fa-paper-plane-o');
     $map = $mail->getDeliveredRoutingMap();
     $routing_detail = null;
     if ($map === null) {
         if ($mail->getStatus() == PhabricatorMailOutboundStatus::STATUS_QUEUE) {
             $routing_result = $this->renderEmptyMessage(pht('This message has not been sent yet, so routing rules have ' . 'not been computed.'));
         } else {
             $routing_result = $this->renderEmptyMessage(pht('This is an older message which predates routing rules.'));
         }
     } else {
         $rule = idx($map, $viewer->getPHID());
         if ($rule === null) {
             $rule = idx($map, 'default');
         }
         if ($rule === null) {
             $routing_result = $this->renderEmptyMessage(pht('No routing rules applied when delivering this message to you.'));
         } else {
             $rule_const = $rule['rule'];
             $reason_phid = $rule['reason'];
             switch ($rule_const) {
                 case PhabricatorMailRoutingRule::ROUTE_AS_NOTIFICATION:
                     $routing_result = pht('This message was routed as a notification because it ' . 'matched %s.', $viewer->renderHandle($reason_phid)->render());
                     break;
                 case PhabricatorMailRoutingRule::ROUTE_AS_MAIL:
                     $routing_result = pht('This message was routed as an email because it matched %s.', $viewer->renderHandle($reason_phid)->render());
                     break;
                 default:
                     $routing_result = pht('Unknown routing rule "%s".', $rule_const);
                     break;
             }
         }
         $routing_rules = $mail->getDeliveredRoutingRules();
         if ($routing_rules) {
             $rules = array();
             foreach ($routing_rules as $rule) {
                 $phids = idx($rule, 'phids');
                 if ($phids === null) {
                     $rules[] = $rule;
                 } else {
                     if (in_array($viewer->getPHID(), $phids)) {
                         $rules[] = $rule;
                     }
                 }
             }
             // Reorder rules by strength.
             foreach ($rules as $key => $rule) {
                 $const = $rule['routingRule'];
                 $phids = $rule['phids'];
                 if ($phids === null) {
                     $type = 'A';
                 } else {
                     $type = 'B';
                 }
                 $rules[$key]['strength'] = sprintf('~%s%08d', $type, PhabricatorMailRoutingRule::getRuleStrength($const));
             }
             $rules = isort($rules, 'strength');
             $routing_detail = id(new PHUIStatusListView());
             foreach ($rules as $rule) {
                 $const = $rule['routingRule'];
                 $phids = $rule['phids'];
                 $name = PhabricatorMailRoutingRule::getRuleName($const);
                 $icon = PhabricatorMailRoutingRule::getRuleIcon($const);
                 $color = PhabricatorMailRoutingRule::getRuleColor($const);
                 if ($phids === null) {
                     $kind = pht('Global');
                 } else {
                     $kind = pht('Personal');
                 }
                 $target = array($kind, ': ', $name);
                 $target = phutil_tag('strong', array(), $target);
                 $item = id(new PHUIStatusItemView())->setTarget($target)->setNote($viewer->renderHandle($rule['reasonPHID']))->setIcon($icon, $color);
                 $routing_detail->addItem($item);
             }
         }
     }
     $properties->addProperty(pht('Effective Rule'), $routing_result);
     if ($routing_detail !== null) {
         $properties->addProperty(pht('All Matching Rules'), $routing_detail);
         $properties->addProperty(null, $this->renderEmptyMessage(pht('Matching rules are listed from weakest to strongest.')));
     }
     return $properties;
 }