/**
   * Implementation of TicketerPlugin API call to retrieve a Jira trouble ticket.
   *
   * @return an OpenNMS
   * @throws PluginException
   */
  @Override
  public Ticket get(String ticketId) throws PluginException {
    JiraRestClient jira = getConnection();
    if (jira == null) {
      return null;
    }

    // w00t
    Issue issue;
    try {
      issue = jira.getIssueClient().getIssue(ticketId).get();
    } catch (InterruptedException | ExecutionException e) {
      throw new PluginException("Failed to get issue with id: " + ticketId, e);
    }

    if (issue != null) {
      Ticket ticket = new Ticket();

      ticket.setId(issue.getKey());
      ticket.setModificationTimestamp(String.valueOf(issue.getUpdateDate().toDate().getTime()));
      ticket.setSummary(issue.getSummary());
      ticket.setDetails(issue.getDescription());
      ticket.setState(getStateFromStatusName(issue.getStatus().getName()));

      return ticket;
    } else {
      return null;
    }
  }
  private void create(Ticket newTicket) throws Otrs31PluginException {
    final String summary = newTicket.getSummary().replaceAll("\\<.*?\\>", "");

    // TODO Check whether we should use the OpenNMS ticket for this
    // The original OTRS plugin checks this and sets if there is a user
    // in the OpenNMS ticket. Suspect this may just cause pain as the
    // OpenNMS user is unlikely to be a valid OTRS customer user.

    final OTRSTicketCreateTicket otrsTicket = new OTRSTicketCreateTicket();
    otrsTicket.setCustomerUser(m_configDao.getDefaultUser());
    otrsTicket.setTitle(summary);
    otrsTicket.setQueue(m_configDao.getQueue());
    otrsTicket.setStateID(openNMSToOTRSState(newTicket.getState()));
    otrsTicket.setPriority(m_configDao.getPriority());
    otrsTicket.setType(m_configDao.getType());

    OTRSArticle otrsArticle = new OTRSArticle();
    // TODO Figure out why we can't set ArticleFrom without an error from OTRS
    // otrsArticle.setFrom(m_configDao.getArticleFrom());
    otrsArticle.setSubject(summary);
    otrsArticle.setBody(newTicket.getDetails());
    otrsArticle.setArticleType(m_configDao.getArticleType());
    otrsArticle.setSenderType(m_configDao.getArticleSenderType());
    otrsArticle.setContentType(m_configDao.getArticleContentType());
    otrsArticle.setHistoryType(m_configDao.getArticleHistoryType());
    otrsArticle.setHistoryComment(m_configDao.getArticleHistoryComment());

    TicketCreate createRequest = new TicketCreate();
    createRequest.setUserLogin(m_configDao.getUserName());
    createRequest.setPassword(m_configDao.getPassword());
    createRequest.setTicket(otrsTicket);
    createRequest.setArticle(otrsArticle);

    TicketCreateResponse response = m_ticketConnector.ticketCreate(createRequest);
    if (response.getError() != null) {
      throw new Otrs31PluginException(response.getError());
    }
    LOG.debug("Created new ticket with ID {}", response.getTicketID().toString());
    newTicket.setId(response.getTicketID().toString());
  }
  /*
   * (non-Javadoc)
   * @see org.opennms.api.integration.ticketing.Plugin#saveOrUpdate(org.opennms.api.integration.ticketing.Ticket)
   */
  @Override
  public void saveOrUpdate(Ticket ticket) throws PluginException {

    JiraRestClient jira = getConnection();

    if (ticket.getId() == null || ticket.getId().equals("")) {
      // If we can't find a ticket with the specified ID then create one.
      IssueInputBuilder builder =
          new IssueInputBuilder(
              getProperties().getProperty("jira.project"),
              Long.valueOf(getProperties().getProperty("jira.type").trim()));
      builder.setReporterName(getProperties().getProperty("jira.username"));
      builder.setSummary(ticket.getSummary());
      builder.setDescription(ticket.getDetails());
      builder.setDueDate(new DateTime(Calendar.getInstance()));

      BasicIssue createdIssue;
      try {
        createdIssue = jira.getIssueClient().createIssue(builder.build()).get();
      } catch (InterruptedException | ExecutionException e) {
        throw new PluginException("Failed to create issue.", e);
      }
      LOG.info("created ticket " + createdIssue);

      ticket.setId(createdIssue.getKey());

    } else {
      // Otherwise update the existing ticket
      LOG.info("Received ticket: {}", ticket.getId());

      Issue issue;
      try {
        issue = jira.getIssueClient().getIssue(ticket.getId()).get();
      } catch (InterruptedException | ExecutionException e) {
        throw new PluginException("Failed to get issue with id:" + ticket.getId(), e);
      }

      Iterable<Transition> transitions;
      try {
        transitions = jira.getIssueClient().getTransitions(issue).get();
      } catch (InterruptedException | ExecutionException e) {
        throw new PluginException(
            "Failed to get transitions for issue with id:" + issue.getId(), e);
      }

      if (Ticket.State.CLOSED.equals(ticket.getState())) {
        Comment comment = Comment.valueOf("Issue resolved by OpenNMS.");
        for (Transition transition : transitions) {
          if (getProperties().getProperty("jira.resolve").equals(transition.getName())) {
            LOG.info("Resolving ticket {}", ticket.getId());
            // Resolve the issue
            try {
              jira.getIssueClient()
                  .transition(issue, new TransitionInput(transition.getId(), comment))
                  .get();
            } catch (InterruptedException | ExecutionException e) {
              throw new PluginException("Failed to get resolve issue with id:" + issue.getId(), e);
            }
            return;
          }
        }
        LOG.warn(
            "Could not resolve ticket {}, no '{}' operation available.",
            ticket.getId(),
            getProperties().getProperty("jira.resolve"));
      } else if (Ticket.State.OPEN.equals(ticket.getState())) {
        Comment comment = Comment.valueOf("Issue reopened by OpenNMS.");
        for (Transition transition : transitions) {
          if (getProperties().getProperty("jira.reopen").equals(transition.getName())) {
            LOG.info("Reopening ticket {}", ticket.getId());
            // Resolve the issue
            try {
              jira.getIssueClient()
                  .transition(issue, new TransitionInput(transition.getId(), comment))
                  .get();
            } catch (InterruptedException | ExecutionException e) {
              throw new PluginException("Failed to reopen issue with id:" + issue.getId(), e);
            }
            return;
          }
        }
        LOG.warn(
            "Could not reopen ticket {}, no '{}' operation available.",
            ticket.getId(),
            getProperties().getProperty("jira.reopen"));
      }
    }
  }
  /*
   * (non-Javadoc)
   * @see org.opennms.api.integration.ticketing.Plugin#get(java.lang.String)
   */
  @Override
  public Ticket get(String ticketId) throws PluginException {
    Objects.requireNonNull(ticketId, "Please provide a ticketId");
    Objects.requireNonNull(
        m_ticketConnector, "The GenericTicketConnector was not initialized properly");

    TicketGet ticketGet = new TicketGet();
    ticketGet.setUserLogin(m_configDao.getUserName());
    ticketGet.setPassword(m_configDao.getPassword());
    ticketGet.setTicketID(new BigInteger[] {new BigInteger(ticketId)});

    TicketGetResponse response = m_ticketConnector.ticketGet(ticketGet);
    LOG.debug("TicketGet responded with {} tickets" + response.getTicketLength());

    if (response.getTicketLength() == 0) {
      // TODO error handling in this case
    }

    if (response.getTicketLength() > 1) {
      LOG.warn("Received more than 1 tickets, ignore all except the first one.");
    }

    final OTRSTicketGetResponseTicket otrsTicket = response.getTicket(0);

    Ticket opennmsTicket = new Ticket();
    // add ticket basics from the OTRS ticket
    opennmsTicket.setId(otrsTicket.getTicketID().toString());
    opennmsTicket.setSummary(otrsTicket.getTitle());

    // Note that we user "Owner" from the OTRS ticket here. There
    // is nothing to ensure
    // That this is a valid OpenNMS user
    opennmsTicket.setUser(otrsTicket.getCustomerUserID());
    opennmsTicket.setState(otrsToOpenNMSState(otrsTicket.getStateID()));

    // add all the article details from the OTRS ticket
    // this is not strictly essential as we have no way of viewing
    // this atm.

    String opennmsTicketDetails = "";
    for (OTRSTicketGetResponseArticle article : otrsTicket.getArticle()) {
      LOG.debug("Adding Article details from OTRS article ID {}", article.getArticleID());
      opennmsTicketDetails =
          new StringBuilder()
              .append(opennmsTicketDetails)
              .append("\n")
              .append("From: ")
              .append(article.getFrom())
              .append("\n")
              .append("Subject: ")
              .append(article.getSubject())
              .append("\n")
              .append("Body: ")
              .append(article.getBody())
              .append("\n")
              .toString();
    }

    opennmsTicket.setDetails(opennmsTicketDetails);

    return opennmsTicket;
  }