/**
   * @param request
   * @param isLogout
   * @param isPassive
   * @param loginPage
   * @return return encoded SAML Auth request
   * @throws SAMLSSOException
   */
  public String buildPostRequest(
      HttpServletRequest request,
      boolean isLogout,
      boolean isPassive,
      String loginPage,
      AuthenticationContext context)
      throws SAMLSSOException {

    doBootstrap();
    RequestAbstractType requestMessage;
    String signatureAlgoProp = null;
    String digestAlgoProp = null;
    String includeCertProp = null;
    String signatureAlgo = null;
    String digestAlgo = null;
    boolean includeCert = false;

    // get Signature Algorithm
    signatureAlgoProp =
        properties.get(IdentityApplicationConstants.Authenticator.SAML2SSO.SIGNATURE_ALGORITHM);
    if (StringUtils.isEmpty(signatureAlgoProp)) {
      signatureAlgoProp = IdentityApplicationConstants.XML.SignatureAlgorithm.RSA_SHA1;
    }
    signatureAlgo =
        IdentityApplicationManagementUtil.getXMLSignatureAlgorithms().get(signatureAlgoProp);

    // get Digest Algorithm
    digestAlgoProp =
        properties.get(IdentityApplicationConstants.Authenticator.SAML2SSO.DIGEST_ALGORITHM);
    if (StringUtils.isEmpty(digestAlgoProp)) {
      digestAlgoProp = IdentityApplicationConstants.XML.DigestAlgorithm.SHA1;
    }
    digestAlgo = IdentityApplicationManagementUtil.getXMLDigestAlgorithms().get(digestAlgoProp);

    includeCertProp =
        properties.get(IdentityApplicationConstants.Authenticator.SAML2SSO.INCLUDE_CERT);
    if (StringUtils.isEmpty(includeCertProp) || Boolean.parseBoolean(includeCertProp)) {
      includeCert = true;
    }

    if (!isLogout) {
      requestMessage = buildAuthnRequest(request, isPassive, loginPage, context);
      if (SSOUtils.isAuthnRequestSigned(properties)) {
        SSOUtils.setSignature(
            requestMessage,
            signatureAlgo,
            digestAlgo,
            includeCert,
            new X509CredentialImpl(context.getTenantDomain(), null));
      }
    } else {
      String username = (String) request.getSession().getAttribute(SSOConstants.LOGOUT_USERNAME);
      String sessionIndex =
          (String) request.getSession().getAttribute(SSOConstants.LOGOUT_SESSION_INDEX);
      String nameQualifier =
          (String) request.getSession().getAttribute(SSOConstants.NAME_QUALIFIER);
      String spNameQualifier =
          (String) request.getSession().getAttribute(SSOConstants.SP_NAME_QUALIFIER);

      requestMessage =
          buildLogoutRequest(username, sessionIndex, loginPage, nameQualifier, spNameQualifier);
      if (SSOUtils.isLogoutRequestSigned(properties)) {
        SSOUtils.setSignature(
            requestMessage,
            signatureAlgo,
            digestAlgo,
            includeCert,
            new X509CredentialImpl(context.getTenantDomain(), null));
      }
    }

    return SSOUtils.encode(SSOUtils.marshall(requestMessage));
  }
  /**
   * Returns the redirection URL with the appended SAML2 Request message
   *
   * @param request SAML 2 request
   * @return redirectionUrl
   */
  @Override
  public String buildRequest(
      HttpServletRequest request,
      boolean isLogout,
      boolean isPassive,
      String loginPage,
      AuthenticationContext context)
      throws SAMLSSOException {

    doBootstrap();
    String contextIdentifier = context.getContextIdentifier();
    RequestAbstractType requestMessage;

    if (request.getParameter(SSOConstants.HTTP_POST_PARAM_SAML2_AUTH_REQ) == null) {
      String queryParam = context.getQueryParams();
      if (queryParam != null) {
        String[] params = queryParam.split("&");
        for (String param : params) {
          String[] values = param.split("=");
          if (values.length == 2 && SSOConstants.HTTP_POST_PARAM_SAML2_AUTH_REQ.equals(values[0])) {
            request.setAttribute(SSOConstants.HTTP_POST_PARAM_SAML2_AUTH_REQ, values[1]);
            break;
          }
        }
      }
    }

    if (!isLogout) {
      requestMessage = buildAuthnRequest(request, isPassive, loginPage, context);
    } else {
      String username = (String) request.getSession().getAttribute(SSOConstants.LOGOUT_USERNAME);
      String sessionIndex =
          (String) request.getSession().getAttribute(SSOConstants.LOGOUT_SESSION_INDEX);
      String nameQualifier =
          (String) request.getSession().getAttribute(SSOConstants.NAME_QUALIFIER);
      String spNameQualifier =
          (String) request.getSession().getAttribute(SSOConstants.SP_NAME_QUALIFIER);

      requestMessage =
          buildLogoutRequest(username, sessionIndex, loginPage, nameQualifier, spNameQualifier);
    }
    String idpUrl = null;
    boolean isSignAuth2SAMLUsingSuperTenant = false;

    String encodedRequestMessage = encodeRequestMessage(requestMessage);
    StringBuilder httpQueryString = new StringBuilder("SAMLRequest=" + encodedRequestMessage);

    try {
      httpQueryString.append("&RelayState=" + URLEncoder.encode(contextIdentifier, "UTF-8").trim());
    } catch (UnsupportedEncodingException e) {
      throw new SAMLSSOException("Error occurred while url encoding RelayState", e);
    }

    if (SSOUtils.isAuthnRequestSigned(properties)) {
      String signatureAlgoProp =
          properties.get(IdentityApplicationConstants.Authenticator.SAML2SSO.SIGNATURE_ALGORITHM);
      if (StringUtils.isEmpty(signatureAlgoProp)) {
        signatureAlgoProp = IdentityApplicationConstants.XML.SignatureAlgorithm.RSA_SHA1;
      }
      String signatureAlgo =
          IdentityApplicationManagementUtil.getXMLSignatureAlgorithms().get(signatureAlgoProp);

      Map<String, String> parameterMap =
          FileBasedConfigurationBuilder.getInstance()
              .getAuthenticatorBean(SSOConstants.AUTHENTICATOR_NAME)
              .getParameterMap();
      if (parameterMap.size() > 0) {
        isSignAuth2SAMLUsingSuperTenant =
            Boolean.parseBoolean(parameterMap.get(SIGN_AUTH2_SAML_USING_SUPER_TENANT));
      }
      if (isSignAuth2SAMLUsingSuperTenant) {
        SSOUtils.addSignatureToHTTPQueryString(
            httpQueryString,
            signatureAlgo,
            new X509CredentialImpl(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, null));
      } else {
        SSOUtils.addSignatureToHTTPQueryString(
            httpQueryString,
            signatureAlgo,
            new X509CredentialImpl(context.getTenantDomain(), null));
      }
    }
    if (loginPage.indexOf("?") > -1) {
      idpUrl = loginPage.concat("&").concat(httpQueryString.toString());
    } else {
      idpUrl = loginPage.concat("?").concat(httpQueryString.toString());
    }
    return idpUrl;
  }