/**
  * This method is use to check the availabilty of given context and if it is available generate
  * new context
  *
  * @param context Page name of the web application
  * @return generated or given context
  */
 private String generateWebAppContext(String context) {
   if (!AppMDAO.isContextExist(context)) {
     return context;
   } else {
     context += (random.nextInt(10 - 0 + 1));
     return generateWebAppContext(context);
   }
 }
  /**
   * 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);
  }
  public int addSubscription(WorkflowDTO workflowDTO) throws AppManagementException {

    SubscriptionExpiryDTO subscriptionExpiryDTO = null;
    if (workflowDTO instanceof SubscriptionExpiryDTO) {
      subscriptionExpiryDTO = (SubscriptionExpiryDTO) workflowDTO;
    } else {
      throw new AppManagementException("Error in casting....");
    }
    Connection connection = null;
    ResultSet resultSet = null;
    PreparedStatement preparedStatement = null;
    AppMDAO appMDAO = new AppMDAO();
    int subscriptionId = -1;

    try {
      connection = APIMgtDBUtil.getConnection();
      int appId =
          appMDAO.getAPIID(
              new APIIdentifier(
                  subscriptionExpiryDTO.getApiProvider(),
                  subscriptionExpiryDTO.getApiName(),
                  subscriptionExpiryDTO.getApiVersion()),
              connection);
      int subscriberId = appMDAO.getSubscriber(subscriptionExpiryDTO.getSubscriber()).getId();

      String sqlQuery =
          "INSERT INTO APM_SUBSCRIPTION_EXT (APP_ID, SUBSCRIBER_ID, SUBSCRIPTION_TYPE, "
              + "SUBSCRIPTION_TIME, EVALUATION_PERIOD, EXPIRED_ON) VALUES (?,?,?,?,?,?)";

      // Adding data to the APM_SUBSCRIPTION_EXT table.
      preparedStatement = connection.prepareStatement(sqlQuery, new String[] {"SUBSCRIPTION_ID"});
      if (connection.getMetaData().getDriverName().contains("PostgreSQL")) {
        preparedStatement = connection.prepareStatement(sqlQuery, new String[] {"subscription_id"});
      }

      preparedStatement.setInt(1, appId);
      preparedStatement.setInt(2, subscriberId);
      preparedStatement.setString(3, subscriptionExpiryDTO.getSubscriptionType());
      preparedStatement.setTimestamp(
          4, new Timestamp(subscriptionExpiryDTO.getSubscriptionTime().getTime()));
      preparedStatement.setInt(5, subscriptionExpiryDTO.getEvaluationPeriod());
      preparedStatement.setTimestamp(
          6, new Timestamp(subscriptionExpiryDTO.getExpireOn().getTime()));

      preparedStatement.executeUpdate();
      ResultSet rs = preparedStatement.getGeneratedKeys();
      while (rs.next()) {
        subscriptionId = rs.getInt(1);
      }
      preparedStatement.close();
      connection.commit();

    } catch (SQLException e) {
      if (connection != null) {
        try {
          connection.rollback();
        } catch (SQLException e1) {
          log.error("Failed to rollback the add subscription ", e);
        }
      }
      handleException("Failed to add subscriber data ", e);
    } finally {
      APIMgtDBUtil.closeAllConnections(preparedStatement, connection, resultSet);
    }
    return subscriptionId;
  }