/**
  * There are two uploader fields in the event, this method gets one of them if one is null.
  *
  * @param event the event to search.
  * @return the uploader if any.
  */
 private static Account findUploader(ChangeBasedEvent event) {
   if (event.getPatchSet() != null && event.getPatchSet().getUploader() != null) {
     return event.getPatchSet().getUploader();
   } else {
     return event.getAccount();
   }
 }
 @Override
 public boolean equals(Object o) {
   if (!getClass().isInstance(o)) {
     return false;
   }
   ChangeBasedEvent event = (ChangeBasedEvent) o;
   if (getEventType() == null) {
     if (event.getEventType() != null) {
       return false;
     }
   } else if (!getEventType().equals(event.getEventType())) {
     return false;
   }
   if (getChange() == null) {
     if (event.getChange() != null) {
       return false;
     }
   } else if (!getChange().equals(event.getChange())) {
     return false;
   }
   if (getPatchSet() == null) {
     if (event.getPatchSet() != null) {
       return false;
     }
   } else if (!getPatchSet().equals(event.getPatchSet())) {
     return false;
   }
   return true;
 }
  /**
   * What it says resolve Endpoint URL.
   *
   * @return the url.
   */
  private String resolveEndpointURL() {
    String gerritFrontEndUrl = config.getGerritFrontEndUrl();
    if (!gerritFrontEndUrl.endsWith("/")) {
      gerritFrontEndUrl = gerritFrontEndUrl + "/";
    }

    ChangeId changeId =
        new ChangeId(
            event.getChange().getProject(),
            event.getChange().getBranch(),
            event.getChange().getId());

    return gerritFrontEndUrl
        + "a/changes/"
        + changeId.asUrlPart()
        + "/revisions/"
        + event.getPatchSet().getRevision()
        + "/review";
  }
  /**
   * Get the front end url from a ChangeBasedEvent.
   *
   * @param event the event
   * @param project the project for which the parameters are being set
   * @return the front end url
   */
  private static String getURL(ChangeBasedEvent event, AbstractProject project) {
    String url = "";
    String serverName = null;
    // Figure out what serverName to use
    if (event.getProvider() != null) {
      serverName = event.getProvider().getName();
    } else if (project != null) {
      String name = GerritTrigger.getTrigger(project).getServerName();
      if (!GerritServer.ANY_SERVER.equals(name)) {
        serverName = name;
      }
    }
    if (serverName == null && PluginImpl.getInstance().getFirstServer() != null) {
      logger.warn(
          "No server could be determined from event or project config, "
              + "defaulting to the first configured server. Event: [{}] Project: [{}]",
          event,
          project);
      serverName = PluginImpl.getInstance().getFirstServer().getName();
    } else if (serverName == null) {
      // We have exhausted all possibilities, time to fail horribly
      throw new IllegalStateException(
          "Cannot determine a Gerrit server to link to. Have you configured one?");
    }

    GerritServer server = PluginImpl.getInstance().getServer(serverName);
    if (server != null) {
      IGerritHudsonTriggerConfig config = server.getConfig();
      if (config != null) {
        url = config.getGerritFrontEndUrlFor(event);
      } else {
        logger.error("Could not find config for Gerrit server {}", serverName);
      }
    } else {
      logger.error("Could not find Gerrit server {}", serverName);
    }
    return url;
  }
  /**
   * Adds or sets all the Gerrit-parameter values to the provided list.
   *
   * @param gerritEvent the event.
   * @param project the project for which the parameters are being set
   * @param parameters the default parameters
   * @see #setOrCreateStringParameterValue(java.util.List, String, boolean)
   */
  public static void setOrCreateParameters(
      GerritTriggeredEvent gerritEvent, AbstractProject project, List<ParameterValue> parameters) {

    boolean noNameAndEmailParameters = false;
    boolean escapeQuotes = false;
    if (project != null) {
      GerritTrigger trigger = GerritTrigger.getTrigger(project);
      if (trigger != null) {
        noNameAndEmailParameters = trigger.isNoNameAndEmailParameters();
        escapeQuotes = trigger.isEscapeQuotes();
      }
    }

    GERRIT_EVENT_TYPE.setOrCreateStringParameterValue(
        parameters, gerritEvent.getEventType().getTypeValue(), escapeQuotes);
    GERRIT_EVENT_HASH.setOrCreateStringParameterValue(
        parameters, String.valueOf(((java.lang.Object) gerritEvent).hashCode()), escapeQuotes);
    if (gerritEvent instanceof ChangeBasedEvent) {
      ChangeBasedEvent event = (ChangeBasedEvent) gerritEvent;
      GERRIT_BRANCH.setOrCreateStringParameterValue(
          parameters, event.getChange().getBranch(), escapeQuotes);
      GERRIT_TOPIC.setOrCreateStringParameterValue(
          parameters, event.getChange().getTopic(), escapeQuotes);
      GERRIT_CHANGE_NUMBER.setOrCreateStringParameterValue(
          parameters, event.getChange().getNumber(), escapeQuotes);
      GERRIT_CHANGE_ID.setOrCreateStringParameterValue(
          parameters, event.getChange().getId(), escapeQuotes);
      String pNumber = null;
      if (null != event.getPatchSet()) {
        pNumber = event.getPatchSet().getNumber();
        GERRIT_PATCHSET_NUMBER.setOrCreateStringParameterValue(parameters, pNumber, escapeQuotes);
        GERRIT_PATCHSET_REVISION.setOrCreateStringParameterValue(
            parameters, event.getPatchSet().getRevision(), escapeQuotes);
        GERRIT_REFSPEC.setOrCreateStringParameterValue(
            parameters, StringUtil.makeRefSpec(event), escapeQuotes);
      }
      GERRIT_PROJECT.setOrCreateStringParameterValue(
          parameters, event.getChange().getProject(), escapeQuotes);
      if (event instanceof ChangeRestored) {
        if (!noNameAndEmailParameters) {
          GERRIT_CHANGE_RESTORER.setOrCreateStringParameterValue(
              parameters, getNameAndEmail(((ChangeRestored) event).getRestorer()), escapeQuotes);
        }
        GERRIT_CHANGE_RESTORER_NAME.setOrCreateStringParameterValue(
            parameters, getName(((ChangeRestored) event).getRestorer()), escapeQuotes);
        GERRIT_CHANGE_RESTORER_EMAIL.setOrCreateStringParameterValue(
            parameters, getEmail(((ChangeRestored) event).getRestorer()), escapeQuotes);
      }
      GERRIT_CHANGE_SUBJECT.setOrCreateStringParameterValue(
          parameters, event.getChange().getSubject(), escapeQuotes);

      String url = getURL(event, project);

      String commitMessage = event.getChange().getCommitMessage();
      if (commitMessage != null) {
        try {
          byte[] encodedBytes = Base64.encodeBase64(commitMessage.getBytes("UTF-8"));
          GERRIT_CHANGE_COMMIT_MESSAGE.setOrCreateStringParameterValue(
              parameters, new String(encodedBytes), escapeQuotes);
        } catch (UnsupportedEncodingException uee) {
          logger.error("Failed to encode commit message as Base64: ", uee);
        }
      }
      GERRIT_CHANGE_URL.setOrCreateStringParameterValue(parameters, url, escapeQuotes);
      if (event instanceof ChangeAbandoned) {
        if (!noNameAndEmailParameters) {
          GERRIT_CHANGE_ABANDONER.setOrCreateStringParameterValue(
              parameters, getNameAndEmail(((ChangeAbandoned) event).getAbandoner()), escapeQuotes);
        }
        GERRIT_CHANGE_ABANDONER_NAME.setOrCreateStringParameterValue(
            parameters, getName(((ChangeAbandoned) event).getAbandoner()), escapeQuotes);
        GERRIT_CHANGE_ABANDONER_EMAIL.setOrCreateStringParameterValue(
            parameters, getEmail(((ChangeAbandoned) event).getAbandoner()), escapeQuotes);
      }
      if (!noNameAndEmailParameters) {
        GERRIT_CHANGE_OWNER.setOrCreateStringParameterValue(
            parameters, getNameAndEmail(event.getChange().getOwner()), escapeQuotes);
      }
      GERRIT_CHANGE_OWNER_NAME.setOrCreateStringParameterValue(
          parameters, getName(event.getChange().getOwner()), escapeQuotes);
      GERRIT_CHANGE_OWNER_EMAIL.setOrCreateStringParameterValue(
          parameters, getEmail(event.getChange().getOwner()), escapeQuotes);
      Account uploader = findUploader(event);
      if (!noNameAndEmailParameters) {
        GERRIT_PATCHSET_UPLOADER.setOrCreateStringParameterValue(
            parameters, getNameAndEmail(uploader), escapeQuotes);
      }
      GERRIT_PATCHSET_UPLOADER_NAME.setOrCreateStringParameterValue(
          parameters, getName(uploader), escapeQuotes);
      GERRIT_PATCHSET_UPLOADER_EMAIL.setOrCreateStringParameterValue(
          parameters, getEmail(uploader), escapeQuotes);
    } else if (gerritEvent instanceof RefUpdated) {
      RefUpdated event = (RefUpdated) gerritEvent;
      GERRIT_REFNAME.setOrCreateStringParameterValue(
          parameters, event.getRefUpdate().getRefName(), escapeQuotes);
      GERRIT_PROJECT.setOrCreateStringParameterValue(
          parameters, event.getRefUpdate().getProject(), escapeQuotes);
      GERRIT_OLDREV.setOrCreateStringParameterValue(
          parameters, event.getRefUpdate().getOldRev(), escapeQuotes);
      GERRIT_NEWREV.setOrCreateStringParameterValue(
          parameters, event.getRefUpdate().getNewRev(), escapeQuotes);
    }
    Account account = gerritEvent.getAccount();
    if (account != null) {
      if (!noNameAndEmailParameters) {
        GERRIT_EVENT_ACCOUNT.setOrCreateStringParameterValue(
            parameters, getNameAndEmail(account), escapeQuotes);
      }
      GERRIT_EVENT_ACCOUNT_NAME.setOrCreateStringParameterValue(
          parameters, getName(account), escapeQuotes);
      GERRIT_EVENT_ACCOUNT_EMAIL.setOrCreateStringParameterValue(
          parameters, getEmail(account), escapeQuotes);
    }
    Provider provider = gerritEvent.getProvider();
    if (provider != null) {
      GERRIT_NAME.setOrCreateStringParameterValue(parameters, provider.getName(), escapeQuotes);
      GERRIT_HOST.setOrCreateStringParameterValue(parameters, provider.getHost(), escapeQuotes);
      GERRIT_PORT.setOrCreateStringParameterValue(parameters, provider.getPort(), escapeQuotes);
      GERRIT_SCHEME.setOrCreateStringParameterValue(parameters, provider.getScheme(), escapeQuotes);
      GERRIT_VERSION.setOrCreateStringParameterValue(
          parameters, provider.getVersion(), escapeQuotes);
    }
  }