private function performInitialValidation()
 {
     $mailboxesService = $this->getGrooveClient()->mailboxes();
     $agentsService = $this->getGrooveClient()->agents();
     // Validation check: Ensure each mailbox in Groove maps to a HelpScout mailbox
     $this->info("Validation check: ensuring each mailbox in Groove maps to a HelpScout mailbox");
     $grooveMailboxes = $this->makeRateLimitedRequest(GROOVE, function () use($mailboxesService) {
         return $mailboxesService->mailboxes()['mailboxes'];
     });
     $hasErrors = false;
     foreach ($grooveMailboxes as $grooveMailbox) {
         $grooveMailboxName = $grooveMailbox['name'];
         if (!($helpscoutMailbox = APIHelper::findMatchingMailboxByName($grooveMailboxName))) {
             $this->error('Missing corresponding HelpScout mailbox named: ' . $grooveMailboxName);
             $hasErrors = true;
         } else {
             $this->info("[ OK ] " . $grooveMailboxName . " mapped to " . $helpscoutMailbox->getEmail() . " (" . $helpscoutMailbox->getId() . ")");
         }
     }
     // Validation check: Ensure each agent has a corresponding user in HelpScout
     $this->info("\nValidation check: ensuring each Groove agent maps to a corresponding HelpScout user");
     $grooveAgents = $this->makeRateLimitedRequest(GROOVE, function () use($agentsService) {
         return $agentsService->list()['agents'];
     });
     foreach ($grooveAgents as $grooveAgent) {
         $grooveAgentEmail = $grooveAgent['email'];
         if (!($helpscoutUser = APIHelper::findMatchingUserWithEmail($grooveAgentEmail))) {
             $this->error('Missing corresponding HelpScout user for email: ' . $grooveAgentEmail);
             $hasErrors = true;
         } else {
             $this->info("[ OK ] " . $grooveAgentEmail . " mapped to HelpScout user " . $helpscoutUser->getFullName() . " (" . $helpscoutUser->getId() . ")");
         }
     }
     if ($hasErrors) {
         $this->error("\nValidation failed. Please correct the above errors, otherwise we cannot proceed.");
         exit;
     }
     $this->info("\nValidation passed.");
 }
 /**
  * @param $consoleCommand SyncCommandBase
  * @return \Closure
  */
 private static function generateProcessor($consoleCommand)
 {
     return function ($ticketsList) use($consoleCommand) {
         $processedTickets = array();
         $checkForDuplicates = $consoleCommand->option('checkDuplicates');
         foreach ($ticketsList as $grooveTicket) {
             $customerEmail = null;
             $grooveTicketNumber = $grooveTicket['number'];
             try {
                 if ($checkForDuplicates) {
                     /* @var $searchResults Collection */
                     $dateString = $grooveTicket['created_at'];
                     $searchResults = $consoleCommand->makeRateLimitedRequest(HELPSCOUT, function () use($consoleCommand, $dateString) {
                         return $consoleCommand->getHelpScoutClient()->conversationSearch("(modifiedAt:[{$dateString} TO {$dateString}])");
                     });
                     if ($searchResults->getCount() > 1) {
                         $helpscoutConversationNumber = null;
                         /* @var $searchConversation SearchConversation */
                         foreach ($searchResults->getItems() as $searchConversation) {
                             if (strcasecmp($searchConversation->getSubject(), $grooveTicket['title']) === 0) {
                                 $helpscoutConversationNumber = $searchConversation->getNumber();
                                 break;
                             }
                         }
                         if ($helpscoutConversationNumber) {
                             $consoleCommand->warn("Warning: Duplicate ticket #{$grooveTicketNumber} \"" . $grooveTicket['title'] . "\" on {$dateString} already uploaded to HelpScout (conversation #{$helpscoutConversationNumber}). Skipping.");
                             continue;
                         }
                     }
                 }
                 $hybridConversation = new HybridConversation();
                 $hybridConversation->setGrooveTicketNumber($grooveTicketNumber);
                 $conversation = new Conversation();
                 $conversation->setType('email');
                 $conversation->setSubject($grooveTicket['title']);
                 // mailbox
                 $mailboxName = $grooveTicket['mailbox'];
                 $assignedMailbox = APIHelper::findMatchingMailboxByName($mailboxName);
                 if (!$assignedMailbox) {
                     $mailboxRef = APIHelper::findMatchingMailboxByEmail(config('services.helpscout.default_mailbox'))->toRef();
                 } else {
                     $mailboxRef = $assignedMailbox->toRef();
                 }
                 $conversation->setMailbox($mailboxRef);
                 if (!$conversation->getMailbox()) {
                     $exception = new ApiException("Mailbox not found in HelpScout: " . $mailboxName);
                     $exception->setErrors(array(['property' => 'mailbox', 'message' => 'Mailbox not found', 'value' => $mailboxName]));
                     throw $exception;
                 }
                 $tags = $grooveTicket['tags'];
                 if ($tags && count($tags) > 0) {
                     $conversation->setTags($tags);
                 }
                 // CustomerRef
                 $matches = array();
                 if (isset($grooveTicket['links']['customer']) && preg_match('@^https://api.groovehq.com/v1/customers/(.*)@i', $grooveTicket['links']['customer']['href'], $matches) === 1) {
                     $customerEmail = $matches[1];
                     if (filter_var($customerEmail, FILTER_VALIDATE_EMAIL)) {
                         $helpscoutPersonRef = new PersonRef((object) array('email' => $customerEmail, 'type' => 'customer'));
                         $conversation->setCustomer($helpscoutPersonRef);
                         $conversation->setCreatedBy($helpscoutPersonRef);
                     } else {
                         $grooveCustomer = $consoleCommand->makeRateLimitedRequest(GROOVE, function () use($consoleCommand, $customerEmail) {
                             return $consoleCommand->getGrooveClient()->customers()->find(['customer_email' => $customerEmail])['customer'];
                         });
                         $helpscoutPersonRef = new PersonRef((object) array('email' => $grooveCustomer['email'], 'type' => 'customer'));
                         list($firstName, $lastName) = APIHelper::extractFirstAndLastNameFromFullName($grooveCustomer['name'], $consoleCommand);
                         $helpscoutPersonRef->setFirstName($firstName);
                         $helpscoutPersonRef->setLastName($lastName);
                         $conversation->setCustomer($helpscoutPersonRef);
                         $conversation->setCreatedBy($helpscoutPersonRef);
                     }
                 } else {
                     throw new ApiException("No customer defined for ticket: #{$grooveTicketNumber}");
                 }
                 // CreatedAt
                 $datetime = new DateTime($grooveTicket['created_at']);
                 $conversation->setCreatedAt($datetime->format('c'));
                 $conversation->setThreads(self::retrieveThreadsForGrooveTicket($consoleCommand, $grooveTicket));
                 $status = APIHelper::getHelpScoutStatusForGrooveState($grooveTicket['state']);
                 if ($status) {
                     $conversation->setStatus($status);
                 } else {
                     $consoleCommand->error("Unknown state provided for Groove ticket #{$grooveTicketNumber}: " . $grooveTicket['state']);
                 }
                 $hybridConversation->setConversation($conversation);
                 $processedTickets[] = $hybridConversation;
             } catch (ApiException $e) {
                 $consoleCommand->error("Failed to create HelpScout conversation for Groove ticket (#{$grooveTicketNumber} created by {$customerEmail} at " . $grooveTicket['created_at'] . "). Message was: \n" . APIHelper::formatApiExceptionArray($e));
             } catch (\CurlException $ce) {
                 $errorMessage = "CurlException encountered for ticket #{$grooveTicketNumber} \"" . $grooveTicket['summary'] . "\"";
                 $consoleCommand->error($errorMessage . ": " . $ce->getMessage());
             } catch (\ErrorException $errex) {
                 $errorMessage = "Error encountered for ticket #{$grooveTicketNumber} \"" . $grooveTicket['summary'] . "\"";
                 $consoleCommand->error($errorMessage . ": " . $errex->getMessage());
             } catch (\Exception $ex) {
                 $errorMessage = "Exception encountered for ticket #{$grooveTicketNumber} \"" . $grooveTicket['summary'] . "\"";
                 $consoleCommand->error($errorMessage . ": " . $ex->getMessage());
             }
         }
         return $processedTickets;
     };
 }