/**
   * This method is use for create,publish and subscribe given web application
   *
   * @param webAppDetail Bean object of the web application
   * @throws AppManagementException Throws this when failed to add an user Throws this when store
   *     session is failed while requesting Throws this when policy id is failed while requesting
   *     Throws this when failed to create,publish or subscribe web application
   */
  public void createAndPublishWebApplication(WebAppDetail webAppDetail)
      throws AppManagementException {
    String currentUserName = webAppDetail.getUserName();
    String creatorSession = webAppDetail.getCreatorSession();
    String storeSession = webAppDetail.getStoreSession();
    String java_policyId = AppMDAO.getDisplayOrderSeqNo();
    webAppDetail.setContext(generateWebAppContext(webAppDetail.getContext()));
    if (currentUserName.equals("admin")) {
      adminPublisherSession = webAppDetail.getCreatorSession();
    } else {
      try {
        adminPublisherSession =
            httpHandler.doPostHttps(
                httpsBackEndUrl + "/publisher/api/authenticate",
                "username="******"&password="******"&action=login",
                "",
                "application/x-www-form-urlencoded");
      } catch (IOException e) {
        String errorMessage = "Error while requesting publisher session";
        log.error(errorMessage, e);
        throw new AppManagementException(errorMessage, e);
      }
    }

    String policyIDResponce = null;
    try {
      policyIDResponce =
          httpHandler.doPostHttps(
                  httpsBackEndUrl
                      + "/publisher/api/entitlement/policy/partial"
                      + "/policyGroup/save",
                  "anonymousAccessToUrlPattern=false&policyGroupName"
                      + "=samples&throttlingTier=Unlimited&objPartialMappings=[]&policyGroupDesc=samples"
                      + "&userRoles=",
                  creatorSession,
                  "application/x-www-form-urlencoded; charset=UTF-8")
              .split(":")[3];
    } catch (IOException e) {
      log.error("Error while requesting a policy id", e);
      throw new AppManagementException("Error while requesting a policy id", e);
    }
    String policyId = policyIDResponce.substring(1, (policyIDResponce.length() - 2)).trim();
    AppCreateRequest appCreateRequest = new AppCreateRequest();
    appCreateRequest.setUritemplate_policyGroupIds("[" + policyId + "]");
    appCreateRequest.setUritemplate_policyGroupId4(policyId);
    appCreateRequest.setUritemplate_policyGroupId3(policyId);
    appCreateRequest.setUritemplate_policyGroupId2(policyId);
    appCreateRequest.setUritemplate_policyGroupId1(policyId);
    appCreateRequest.setUritemplate_policyGroupId0(policyId);
    appCreateRequest.setOverview_provider(currentUserName);
    appCreateRequest.setUritemplate_javaPolicyIds("[" + java_policyId + "]");
    appCreateRequest.setClaimPropertyCounter(webAppDetail.getClaims().size() + "");
    appCreateRequest.setOverview_name(webAppDetail.getWebAppName());
    appCreateRequest.setOverview_displayName(webAppDetail.getDisplayName());
    appCreateRequest.setOverview_context(webAppDetail.getContext());
    appCreateRequest.setOverview_version(webAppDetail.getVersion());
    appCreateRequest.setOverview_trackingCode(appCreateRequest.generateTrackingID());
    appCreateRequest.setOverview_transports("http");
    appCreateRequest.setOverview_webAppUrl(
        httpBackEndUrl + "/" + webAppDetail.getWarFileName() + "/");
    appCreateRequest.setOverview_treatAsASite(webAppDetail.getTreatAsASite());
    String UUID = null;
    String errorMessage = "Error while creating a web application" + webAppDetail.getDisplayName();
    try {
      UUID = createWebApplication(appCreateRequest.generateRequestParameters(), webAppDetail);
    } catch (IOException e) {
      log.error(errorMessage, e);
      throw new AppManagementException(errorMessage, e);
    } catch (RegistryException e) {
      log.error(errorMessage, e);
      throw new AppManagementException(errorMessage, e);
    } catch (InterruptedException e) {
      log.error(errorMessage, e);
      throw new AppManagementException(errorMessage, e);
    }
    try {
      applicationPublisher.publishApplication("webapp", UUID, adminPublisherSession);
    } catch (IOException e) {
      String publishingErrorMessage =
          "Error while publishing a web application " + webAppDetail.getDisplayName();
      log.error(publishingErrorMessage, e);
      throw new AppManagementException(publishingErrorMessage, e);
    }
    log.info(appCreateRequest.getOverview_name() + " published and UUID is " + UUID);
    try {
      applicationSubscriber.subscribeApplication(appCreateRequest, storeSession, currentUserName);
    } catch (IOException e) {
      String subscribingErrorMessage =
          "Error while subscribing a web application " + webAppDetail.getDisplayName();
      log.error(subscribingErrorMessage, e);
      throw new AppManagementException(subscribingErrorMessage, e);
    }
    log.info(
        appCreateRequest.getOverview_name()
            + "application subscribed by subsciber_"
            + currentUserName);
  }
  /**
   * This method is use for create web application
   *
   * @param payload request payload for web app create api
   * @param webAppDetail bean object of the web application
   * @throws IOException Throws this when failed to create web application
   * @throws RegistryException Throws this when UUID failed while requesting
   * @throws AppManagementException Throws this when gateway port failed while retrieving
   * @throws java.lang.InterruptedException Throws this when thread failed
   */
  private String createWebApplication(String payload, WebAppDetail webAppDetail)
      throws IOException, RegistryException, AppManagementException, InterruptedException {
    String currentUserName = webAppDetail.getUserName();
    String creatorSession = webAppDetail.getCreatorSession();
    httpHandler.doPostHttps(
        httpsBackEndUrl + "/publisher/asset/webapp",
        payload,
        creatorSession,
        "application/x-www-form-urlencoded");

    JSONArray claimsAry = new JSONArray();
    ConcurrentHashMap<String, String[]> claimMap = webAppDetail.getClaims();
    Iterator entries = claimMap.entrySet().iterator();
    while (entries.hasNext()) {
      Map.Entry thisEntry = (Map.Entry) entries.next();
      String claimName = ((String[]) thisEntry.getValue())[0];
      claimsAry.add(claimName);
    }
    JSONObject configJson = new JSONObject();
    configJson.put("provider", "wso2is-5.0.0"); // use a constant
    configJson.put("logout_url", "");
    configJson.put("claims", claimsAry);
    configJson.put("app_name", webAppDetail.getWebAppName());
    configJson.put("app_verison", webAppDetail.getVersion());
    configJson.put("app_transport", "http");
    configJson.put("app_context", webAppDetail.getContext());
    configJson.put("app_provider", webAppDetail.getUserName());
    configJson.put("app_allowAnonymous", "false");
    configJson.put("app_acsURL", "");
    httpHandler.doPostHttps(
        httpsBackEndUrl + "/publisher/api/sso/addConfig",
        configJson.toJSONString(),
        creatorSession,
        "application/json; charset=UTF-8");
    String appPath =
        "/_system/governance/appmgt/applicationdata/provider/"
            + currentUserName
            + "/"
            + webAppDetail.getWebAppName()
            + "/1.0.0/webapp";
    String UUID = wsRegistryServiceClient.getUUID(appPath);
    String trackingIDResponse =
        httpHandler
            .doGet(
                httpsBackEndUrl + "/publisher/api/asset/webapp/trackingid/" + UUID,
                "",
                creatorSession,
                "")
            .split(":")[1]
            .trim();
    String trackingID = trackingIDResponse.substring(1, (trackingIDResponse.length() - 2));
    webAppDetail.setTrackingCode(trackingID);
    invokeStatistcsJavascriptBuilder =
        new InvokeStatistcsJavascriptBuilder(
            trackingID, ipAddress, Configuration.getGatewayPort("http"));
    if (webAppDetail.getWebAppName().equals("PlanYourTrip_" + currentUserName)) {
      invokeStatistcsJavascriptBuilder.buildInvokeStaticsJavascriptFile(
          appmHomePath + "/repository/deployment/server/webapps/plan-your-trip-1.2.0");
    } else if (webAppDetail.getWebAppName().equals("TravelBooking_" + currentUserName)) {
      invokeStatistcsJavascriptBuilder.buildInvokeStaticsJavascriptFile(
          appmHomePath + "/repository/deployment/server/webapps/travel-booking-1.2.0/js");
    }
    log.info(webAppDetail.getWebAppName() + " created and UUID is : " + UUID);
    return UUID;
  }