/**
   * Handles the request for http post binding
   *
   * @param request The HTTP request with SAML2 message
   * @param response The HTTP response
   * @param isLogout Whether the request is a logout request
   * @throws SSOAgentException
   */
  public String buildPostRequest(
      HttpServletRequest request, HttpServletResponse response, boolean isLogout)
      throws SSOAgentException {

    RequestAbstractType requestMessage = null;
    if (!isLogout) {
      requestMessage = buildAuthnRequest(request);
      if (ssoAgentConfig.getSAML2().isRequestSigned()) {
        requestMessage =
            SSOAgentUtils.setSignature(
                (AuthnRequest) requestMessage,
                XMLSignature.ALGO_ID_SIGNATURE_RSA,
                new X509CredentialImpl(ssoAgentConfig.getSAML2().getSSOAgentX509Credential()));
      }

    } else {
      LoggedInSessionBean sessionBean =
          (LoggedInSessionBean)
              request.getSession(false).getAttribute(SSOAgentConstants.SESSION_BEAN_NAME);
      if (sessionBean != null) {
        requestMessage =
            buildLogoutRequest(
                sessionBean.getSAML2SSO().getSubjectId(),
                sessionBean.getSAML2SSO().getSessionIndex());
        if (ssoAgentConfig.getSAML2().isRequestSigned()) {
          requestMessage =
              SSOAgentUtils.setSignature(
                  (LogoutRequest) requestMessage,
                  XMLSignature.ALGO_ID_SIGNATURE_RSA,
                  new X509CredentialImpl(ssoAgentConfig.getSAML2().getSSOAgentX509Credential()));
        }
      } else {
        throw new SSOAgentException("SLO Request can not be built. SSO Session is null");
      }
    }
    String encodedRequestMessage =
        encodeRequestMessage(requestMessage, SAMLConstants.SAML2_POST_BINDING_URI);

    Map<String, String[]> paramsMap = new HashMap<String, String[]>();
    paramsMap.put(
        SSOAgentConstants.SAML2SSO.HTTP_POST_PARAM_SAML2_AUTH_REQ,
        new String[] {encodedRequestMessage});
    if (ssoAgentConfig.getSAML2().getRelayState() != null) {
      paramsMap.put(
          RelayState.DEFAULT_ELEMENT_LOCAL_NAME,
          new String[] {ssoAgentConfig.getSAML2().getRelayState()});
    }

    // Add any additional parameters defined
    if (ssoAgentConfig.getQueryParams() != null && !ssoAgentConfig.getQueryParams().isEmpty()) {
      paramsMap.putAll(ssoAgentConfig.getQueryParams());
    }

    StringBuilder htmlParams = new StringBuilder();
    for (Map.Entry<String, String[]> entry : paramsMap.entrySet()) {
      if (entry.getKey() != null && entry.getValue() != null && entry.getValue().length > 0) {
        for (String param : entry.getValue()) {
          htmlParams
              .append("<input type='hidden' name='")
              .append(entry.getKey())
              .append("' value='")
              .append(param)
              .append("'>\n");
        }
      }
    }
    String htmlPayload = ssoAgentConfig.getSAML2().getPostBindingRequestHTMLPayload();
    if (htmlPayload == null || !htmlPayload.contains("<!--$saml_params-->")) {
      htmlPayload =
          "<html>\n"
              + "<body>\n"
              + "<p>You are now redirected back to "
              + ssoAgentConfig.getSAML2().getIdPURL()
              + " \n"
              + "If the redirection fails, please click the post button.</p>\n"
              + "<form method='post' action='"
              + ssoAgentConfig.getSAML2().getIdPURL()
              + "'>\n"
              + "<p>\n"
              + htmlParams.toString()
              + "<button type='submit'>POST</button>\n"
              + "</p>\n"
              + "</form>\n"
              + "<script type='text/javascript'>\n"
              + "document.forms[0].submit();\n"
              + "</script>\n"
              + "</body>\n"
              + "</html>";
    } else {
      htmlPayload = htmlPayload.replace("<!--$saml_params-->", htmlParams.toString());
    }
    return htmlPayload;
  }
  /**
   * Returns the redirection URL with the appended SAML2 Request message
   *
   * @param request SAML 2 request
   * @return redirectionUrl
   */
  public String buildRedirectRequest(HttpServletRequest request, boolean isLogout)
      throws SSOAgentException {

    RequestAbstractType requestMessage = null;
    if (!isLogout) {
      requestMessage = buildAuthnRequest(request);
    } else {
      LoggedInSessionBean sessionBean =
          (LoggedInSessionBean)
              request.getSession(false).getAttribute(SSOAgentConstants.SESSION_BEAN_NAME);
      if (sessionBean != null) {
        requestMessage =
            buildLogoutRequest(
                sessionBean.getSAML2SSO().getSubjectId(),
                sessionBean.getSAML2SSO().getSessionIndex());
      } else {
        throw new SSOAgentException("SLO Request can not be built. SSO Session is NULL");
      }
    }
    String idpUrl = null;

    String encodedRequestMessage =
        encodeRequestMessage(requestMessage, SAMLConstants.SAML2_REDIRECT_BINDING_URI);
    StringBuilder httpQueryString =
        new StringBuilder(
            SSOAgentConstants.SAML2SSO.HTTP_POST_PARAM_SAML2_AUTH_REQ
                + "="
                + encodedRequestMessage);

    String relayState = ssoAgentConfig.getSAML2().getRelayState();
    if (relayState != null) {
      try {
        httpQueryString.append(
            "&"
                + RelayState.DEFAULT_ELEMENT_LOCAL_NAME
                + "="
                + URLEncoder.encode(relayState, "UTF-8").trim());
      } catch (UnsupportedEncodingException e) {
        throw new SSOAgentException(
            "Error occurred while URLEncoding " + RelayState.DEFAULT_ELEMENT_LOCAL_NAME, e);
      }
    }

    if (ssoAgentConfig.getQueryParams() != null && !ssoAgentConfig.getQueryParams().isEmpty()) {
      StringBuilder builder = new StringBuilder();
      for (Map.Entry<String, String[]> entry : ssoAgentConfig.getQueryParams().entrySet()) {
        if (entry.getKey() != null && entry.getValue() != null && entry.getValue().length > 0) {
          for (String param : entry.getValue()) {
            builder.append("&").append(entry.getKey()).append("=").append(param);
          }
        }
      }
      httpQueryString.append(builder);
    }

    if (ssoAgentConfig.getSAML2().isRequestSigned()) {
      SSOAgentUtils.addDeflateSignatureToHTTPQueryString(
          httpQueryString,
          new X509CredentialImpl(ssoAgentConfig.getSAML2().getSSOAgentX509Credential()));
    }

    if (ssoAgentConfig.getSAML2().getIdPURL().indexOf("?") > -1) {
      idpUrl = ssoAgentConfig.getSAML2().getIdPURL().concat("&").concat(httpQueryString.toString());
    } else {
      idpUrl = ssoAgentConfig.getSAML2().getIdPURL().concat("?").concat(httpQueryString.toString());
    }
    return idpUrl;
  }