/**
   * Factory method for creating the specific server requests objects. Creates requests according to
   * the request path.
   *
   * @param requestPath Path for the server request. see {@link Defines.RequestPath}
   * @param post A {@link JSONObject} object containing post data stored as key-value pairs.
   * @param context Application context.
   * @return A {@link ServerRequest} object for the given Post data.
   */
  private static ServerRequest getExtendedServerRequest(
      String requestPath, JSONObject post, Context context) {
    ServerRequest extendedReq = null;

    if (requestPath.equalsIgnoreCase(Defines.RequestPath.CompletedAction.getPath())) {
      extendedReq = new ServerRequestActionCompleted(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.ApplyReferralCode.getPath())) {
      extendedReq = new ServerRequestApplyReferralCode(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.GetURL.getPath())) {
      extendedReq = new ServerRequestCreateUrl(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.GetReferralCode.getPath())) {
      extendedReq = new ServerRequestGetReferralCode(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.Referrals.getPath())) {
      extendedReq = new ServerRequestGetReferralCount(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.GetCreditHistory.getPath())) {
      extendedReq = new ServerRequestGetRewardHistory(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.GetCredits.getPath())) {
      extendedReq = new ServerRequestGetRewards(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.IdentifyUser.getPath())) {
      extendedReq = new ServerRequestIdentifyUserRequest(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.Logout.getPath())) {
      extendedReq = new ServerRequestLogout(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.RedeemRewards.getPath())) {
      extendedReq = new ServerRequestRedeemRewards(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.RegisterClose.getPath())) {
      extendedReq = new ServerRequestRegisterClose(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.RegisterInstall.getPath())) {
      extendedReq = new ServerRequestRegisterInstall(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.RegisterOpen.getPath())) {
      extendedReq = new ServerRequestRegisterOpen(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.SendAPPList.getPath())) {
      extendedReq = new ServerRequestSendAppList(requestPath, post, context);
    } else if (requestPath.equalsIgnoreCase(Defines.RequestPath.ValidateReferralCode.getPath())) {
      extendedReq = new ServerRequestValidateReferralCode(requestPath, post, context);
    }

    return extendedReq;
  }
  /**
   * Create an instance of {@link ServerRequestRegisterInstall} to notify Branch API on a new
   * install.
   *
   * @param context Current {@link Application} context
   * @param callback A {@link Branch.BranchReferralInitListener} callback instance that will return
   *     the data associated with new install registration.
   * @param sysObserver {@link SystemObserver} instance.
   * @param installID installation ID. .
   */
  public ServerRequestRegisterInstall(
      Context context,
      Branch.BranchReferralInitListener callback,
      SystemObserver sysObserver,
      String installID) {

    super(context, Defines.RequestPath.RegisterInstall.getPath());

    callback_ = callback;
    JSONObject installPost = new JSONObject();
    try {
      if (!installID.equals(PrefHelper.NO_STRING_VALUE))
        installPost.put(Defines.Jsonkey.LinkClickID.getKey(), installID);
      String uniqId = sysObserver.getUniqueID(prefHelper_.getExternDebug());
      if (!uniqId.equals(SystemObserver.BLANK)) {
        installPost.put(Defines.Jsonkey.HardwareID.getKey(), uniqId);
        installPost.put(Defines.Jsonkey.IsHardwareIDReal.getKey(), sysObserver.hasRealHardwareId());
      }
      if (!sysObserver.getAppVersion().equals(SystemObserver.BLANK))
        installPost.put(Defines.Jsonkey.AppVersion.getKey(), sysObserver.getAppVersion());
      if (!sysObserver.getCarrier().equals(SystemObserver.BLANK))
        installPost.put(Defines.Jsonkey.Carrier.getKey(), sysObserver.getCarrier());
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
        installPost.put(Defines.Jsonkey.Bluetooth.getKey(), sysObserver.getBluetoothPresent());
      }
      if (!sysObserver.getBluetoothVersion().equals(SystemObserver.BLANK))
        installPost.put(
            Defines.Jsonkey.BluetoothVersion.getKey(), sysObserver.getBluetoothVersion());
      installPost.put(Defines.Jsonkey.HasNfc.getKey(), sysObserver.getNFCPresent());
      installPost.put(Defines.Jsonkey.HasTelephone.getKey(), sysObserver.getTelephonePresent());
      if (!sysObserver.getPhoneBrand().equals(SystemObserver.BLANK))
        installPost.put(Defines.Jsonkey.Brand.getKey(), sysObserver.getPhoneBrand());
      if (!sysObserver.getPhoneModel().equals(SystemObserver.BLANK))
        installPost.put(Defines.Jsonkey.Model.getKey(), sysObserver.getPhoneModel());
      if (!sysObserver.getOS().equals(SystemObserver.BLANK))
        installPost.put(Defines.Jsonkey.OS.getKey(), sysObserver.getOS());
      // Read and update the URI scheme only if running in debug mode
      if (prefHelper_.isDebug()) {
        String uriScheme = sysObserver.getURIScheme();
        if (!uriScheme.equals(SystemObserver.BLANK))
          installPost.put(Defines.Jsonkey.URIScheme.getKey(), uriScheme);
      }
      installPost.put(Defines.Jsonkey.OSVersion.getKey(), sysObserver.getOSVersion());
      DisplayMetrics dMetrics = sysObserver.getScreenDisplay();
      installPost.put(Defines.Jsonkey.ScreenDpi.getKey(), dMetrics.densityDpi);
      installPost.put(Defines.Jsonkey.ScreenHeight.getKey(), dMetrics.heightPixels);
      installPost.put(Defines.Jsonkey.ScreenWidth.getKey(), dMetrics.widthPixels);
      installPost.put(Defines.Jsonkey.WiFi.getKey(), sysObserver.getWifiConnected());
      installPost.put(Defines.Jsonkey.IsReferrable.getKey(), prefHelper_.getIsReferrable());
      installPost.put(Defines.Jsonkey.Update.getKey(), sysObserver.getUpdateState(true));
      if (!prefHelper_.getLinkClickIdentifier().equals(PrefHelper.NO_STRING_VALUE)) {
        installPost.put(
            Defines.Jsonkey.LinkIdentifier.getKey(), prefHelper_.getLinkClickIdentifier());
      }

      installPost.put(
          Defines.Jsonkey.Debug.getKey(), prefHelper_.isDebug() || prefHelper_.getExternDebug());
      setPost(installPost);

    } catch (JSONException ex) {
      ex.printStackTrace();
      constructError_ = true;
    }
  }