/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

#pragma once
#include <aws/compute-optimizer/ComputeOptimizer_EXPORTS.h>
#include <aws/compute-optimizer/model/AutoScalingGroupConfiguration.h>
#include <aws/compute-optimizer/model/AutoScalingGroupRecommendationOption.h>
#include <aws/compute-optimizer/model/CurrentPerformanceRisk.h>
#include <aws/compute-optimizer/model/EffectiveRecommendationPreferences.h>
#include <aws/compute-optimizer/model/Finding.h>
#include <aws/compute-optimizer/model/GpuInfo.h>
#include <aws/compute-optimizer/model/InferredWorkloadType.h>
#include <aws/compute-optimizer/model/UtilizationMetric.h>
#include <aws/core/utils/DateTime.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/core/utils/memory/stl/AWSVector.h>

#include <utility>

namespace Aws {
namespace Utils {
namespace Json {
class JsonValue;
class JsonView;
}  // namespace Json
}  // namespace Utils
namespace ComputeOptimizer {
namespace Model {

/**
 * <p>Describes an Amazon EC2 Auto Scaling group recommendation.</p><p><h3>See
 * Also:</h3>   <a
 * href="http://docs.aws.amazon.com/goto/WebAPI/compute-optimizer-2019-11-01/AutoScalingGroupRecommendation">AWS
 * API Reference</a></p>
 */
class AutoScalingGroupRecommendation {
 public:
  AWS_COMPUTEOPTIMIZER_API AutoScalingGroupRecommendation() = default;
  AWS_COMPUTEOPTIMIZER_API AutoScalingGroupRecommendation(Aws::Utils::Json::JsonView jsonValue);
  AWS_COMPUTEOPTIMIZER_API AutoScalingGroupRecommendation& operator=(Aws::Utils::Json::JsonView jsonValue);
  AWS_COMPUTEOPTIMIZER_API Aws::Utils::Json::JsonValue Jsonize() const;

  ///@{
  /**
   * <p>The Amazon Web Services account ID of the Amazon EC2 Auto Scaling group.</p>
   */
  inline const Aws::String& GetAccountId() const { return m_accountId; }
  inline bool AccountIdHasBeenSet() const { return m_accountIdHasBeenSet; }
  template <typename AccountIdT = Aws::String>
  void SetAccountId(AccountIdT&& value) {
    m_accountIdHasBeenSet = true;
    m_accountId = std::forward<AccountIdT>(value);
  }
  template <typename AccountIdT = Aws::String>
  AutoScalingGroupRecommendation& WithAccountId(AccountIdT&& value) {
    SetAccountId(std::forward<AccountIdT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The Amazon Resource Name (ARN) of the Amazon EC2 Auto Scaling group.</p>
   */
  inline const Aws::String& GetAutoScalingGroupArn() const { return m_autoScalingGroupArn; }
  inline bool AutoScalingGroupArnHasBeenSet() const { return m_autoScalingGroupArnHasBeenSet; }
  template <typename AutoScalingGroupArnT = Aws::String>
  void SetAutoScalingGroupArn(AutoScalingGroupArnT&& value) {
    m_autoScalingGroupArnHasBeenSet = true;
    m_autoScalingGroupArn = std::forward<AutoScalingGroupArnT>(value);
  }
  template <typename AutoScalingGroupArnT = Aws::String>
  AutoScalingGroupRecommendation& WithAutoScalingGroupArn(AutoScalingGroupArnT&& value) {
    SetAutoScalingGroupArn(std::forward<AutoScalingGroupArnT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The name of the Amazon EC2 Auto Scaling group.</p>
   */
  inline const Aws::String& GetAutoScalingGroupName() const { return m_autoScalingGroupName; }
  inline bool AutoScalingGroupNameHasBeenSet() const { return m_autoScalingGroupNameHasBeenSet; }
  template <typename AutoScalingGroupNameT = Aws::String>
  void SetAutoScalingGroupName(AutoScalingGroupNameT&& value) {
    m_autoScalingGroupNameHasBeenSet = true;
    m_autoScalingGroupName = std::forward<AutoScalingGroupNameT>(value);
  }
  template <typename AutoScalingGroupNameT = Aws::String>
  AutoScalingGroupRecommendation& WithAutoScalingGroupName(AutoScalingGroupNameT&& value) {
    SetAutoScalingGroupName(std::forward<AutoScalingGroupNameT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The finding classification of the Amazon EC2 Auto Scaling group.</p>
   * <p>Findings for Amazon EC2 Auto Scaling groups include:</p> <ul> <li> <p> <b>
   * <code>NotOptimized</code> </b>—An Amazon EC2 Auto Scaling group is considered
   * not optimized when Compute Optimizer identifies a recommendation that can
   * provide better performance for your workload.</p> </li> <li> <p> <b>
   * <code>Optimized</code> </b>—An Amazon EC2 Auto Scaling group is considered
   * optimized when Compute Optimizer determines that the group is correctly
   * provisioned to run your workload based on the chosen instance type. For
   * optimized resources, Compute Optimizer might recommend a new generation instance
   * type.</p> </li> </ul>
   */
  inline Finding GetFinding() const { return m_finding; }
  inline bool FindingHasBeenSet() const { return m_findingHasBeenSet; }
  inline void SetFinding(Finding value) {
    m_findingHasBeenSet = true;
    m_finding = value;
  }
  inline AutoScalingGroupRecommendation& WithFinding(Finding value) {
    SetFinding(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>An array of objects that describe the utilization metrics of the Amazon EC2
   * Auto Scaling group.</p>
   */
  inline const Aws::Vector<UtilizationMetric>& GetUtilizationMetrics() const { return m_utilizationMetrics; }
  inline bool UtilizationMetricsHasBeenSet() const { return m_utilizationMetricsHasBeenSet; }
  template <typename UtilizationMetricsT = Aws::Vector<UtilizationMetric>>
  void SetUtilizationMetrics(UtilizationMetricsT&& value) {
    m_utilizationMetricsHasBeenSet = true;
    m_utilizationMetrics = std::forward<UtilizationMetricsT>(value);
  }
  template <typename UtilizationMetricsT = Aws::Vector<UtilizationMetric>>
  AutoScalingGroupRecommendation& WithUtilizationMetrics(UtilizationMetricsT&& value) {
    SetUtilizationMetrics(std::forward<UtilizationMetricsT>(value));
    return *this;
  }
  template <typename UtilizationMetricsT = UtilizationMetric>
  AutoScalingGroupRecommendation& AddUtilizationMetrics(UtilizationMetricsT&& value) {
    m_utilizationMetricsHasBeenSet = true;
    m_utilizationMetrics.emplace_back(std::forward<UtilizationMetricsT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The number of days for which utilization metrics were analyzed for the Amazon
   * EC2 Auto Scaling group.</p>
   */
  inline double GetLookBackPeriodInDays() const { return m_lookBackPeriodInDays; }
  inline bool LookBackPeriodInDaysHasBeenSet() const { return m_lookBackPeriodInDaysHasBeenSet; }
  inline void SetLookBackPeriodInDays(double value) {
    m_lookBackPeriodInDaysHasBeenSet = true;
    m_lookBackPeriodInDays = value;
  }
  inline AutoScalingGroupRecommendation& WithLookBackPeriodInDays(double value) {
    SetLookBackPeriodInDays(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>An array of objects that describe the current configuration of the Amazon EC2
   * Auto Scaling group.</p>
   */
  inline const AutoScalingGroupConfiguration& GetCurrentConfiguration() const { return m_currentConfiguration; }
  inline bool CurrentConfigurationHasBeenSet() const { return m_currentConfigurationHasBeenSet; }
  template <typename CurrentConfigurationT = AutoScalingGroupConfiguration>
  void SetCurrentConfiguration(CurrentConfigurationT&& value) {
    m_currentConfigurationHasBeenSet = true;
    m_currentConfiguration = std::forward<CurrentConfigurationT>(value);
  }
  template <typename CurrentConfigurationT = AutoScalingGroupConfiguration>
  AutoScalingGroupRecommendation& WithCurrentConfiguration(CurrentConfigurationT&& value) {
    SetCurrentConfiguration(std::forward<CurrentConfigurationT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p> Describes the GPU accelerator settings for the current instance type of the
   * Amazon EC2 Auto Scaling group. </p>
   */
  inline const GpuInfo& GetCurrentInstanceGpuInfo() const { return m_currentInstanceGpuInfo; }
  inline bool CurrentInstanceGpuInfoHasBeenSet() const { return m_currentInstanceGpuInfoHasBeenSet; }
  template <typename CurrentInstanceGpuInfoT = GpuInfo>
  void SetCurrentInstanceGpuInfo(CurrentInstanceGpuInfoT&& value) {
    m_currentInstanceGpuInfoHasBeenSet = true;
    m_currentInstanceGpuInfo = std::forward<CurrentInstanceGpuInfoT>(value);
  }
  template <typename CurrentInstanceGpuInfoT = GpuInfo>
  AutoScalingGroupRecommendation& WithCurrentInstanceGpuInfo(CurrentInstanceGpuInfoT&& value) {
    SetCurrentInstanceGpuInfo(std::forward<CurrentInstanceGpuInfoT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>An array of objects that describe the recommendation options for the Amazon
   * EC2 Auto Scaling group.</p>
   */
  inline const Aws::Vector<AutoScalingGroupRecommendationOption>& GetRecommendationOptions() const { return m_recommendationOptions; }
  inline bool RecommendationOptionsHasBeenSet() const { return m_recommendationOptionsHasBeenSet; }
  template <typename RecommendationOptionsT = Aws::Vector<AutoScalingGroupRecommendationOption>>
  void SetRecommendationOptions(RecommendationOptionsT&& value) {
    m_recommendationOptionsHasBeenSet = true;
    m_recommendationOptions = std::forward<RecommendationOptionsT>(value);
  }
  template <typename RecommendationOptionsT = Aws::Vector<AutoScalingGroupRecommendationOption>>
  AutoScalingGroupRecommendation& WithRecommendationOptions(RecommendationOptionsT&& value) {
    SetRecommendationOptions(std::forward<RecommendationOptionsT>(value));
    return *this;
  }
  template <typename RecommendationOptionsT = AutoScalingGroupRecommendationOption>
  AutoScalingGroupRecommendation& AddRecommendationOptions(RecommendationOptionsT&& value) {
    m_recommendationOptionsHasBeenSet = true;
    m_recommendationOptions.emplace_back(std::forward<RecommendationOptionsT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The timestamp of when the Amazon EC2 Auto Scaling group recommendation was
   * last generated.</p>
   */
  inline const Aws::Utils::DateTime& GetLastRefreshTimestamp() const { return m_lastRefreshTimestamp; }
  inline bool LastRefreshTimestampHasBeenSet() const { return m_lastRefreshTimestampHasBeenSet; }
  template <typename LastRefreshTimestampT = Aws::Utils::DateTime>
  void SetLastRefreshTimestamp(LastRefreshTimestampT&& value) {
    m_lastRefreshTimestampHasBeenSet = true;
    m_lastRefreshTimestamp = std::forward<LastRefreshTimestampT>(value);
  }
  template <typename LastRefreshTimestampT = Aws::Utils::DateTime>
  AutoScalingGroupRecommendation& WithLastRefreshTimestamp(LastRefreshTimestampT&& value) {
    SetLastRefreshTimestamp(std::forward<LastRefreshTimestampT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The risk of the current Amazon EC2 Auto Scaling group not meeting the
   * performance needs of its workloads. The higher the risk, the more likely the
   * current Amazon EC2 Auto Scaling group configuration has insufficient capacity
   * and cannot meet workload requirements.</p>
   */
  inline CurrentPerformanceRisk GetCurrentPerformanceRisk() const { return m_currentPerformanceRisk; }
  inline bool CurrentPerformanceRiskHasBeenSet() const { return m_currentPerformanceRiskHasBeenSet; }
  inline void SetCurrentPerformanceRisk(CurrentPerformanceRisk value) {
    m_currentPerformanceRiskHasBeenSet = true;
    m_currentPerformanceRisk = value;
  }
  inline AutoScalingGroupRecommendation& WithCurrentPerformanceRisk(CurrentPerformanceRisk value) {
    SetCurrentPerformanceRisk(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>An object that describes the effective recommendation preferences for the
   * Amazon EC2 Auto Scaling group.</p>
   */
  inline const EffectiveRecommendationPreferences& GetEffectiveRecommendationPreferences() const {
    return m_effectiveRecommendationPreferences;
  }
  inline bool EffectiveRecommendationPreferencesHasBeenSet() const { return m_effectiveRecommendationPreferencesHasBeenSet; }
  template <typename EffectiveRecommendationPreferencesT = EffectiveRecommendationPreferences>
  void SetEffectiveRecommendationPreferences(EffectiveRecommendationPreferencesT&& value) {
    m_effectiveRecommendationPreferencesHasBeenSet = true;
    m_effectiveRecommendationPreferences = std::forward<EffectiveRecommendationPreferencesT>(value);
  }
  template <typename EffectiveRecommendationPreferencesT = EffectiveRecommendationPreferences>
  AutoScalingGroupRecommendation& WithEffectiveRecommendationPreferences(EffectiveRecommendationPreferencesT&& value) {
    SetEffectiveRecommendationPreferences(std::forward<EffectiveRecommendationPreferencesT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The applications that might be running on the instances in the Amazon EC2
   * Auto Scaling group as inferred by Compute Optimizer.</p> <p>Compute Optimizer
   * can infer if one of the following applications might be running on the
   * instances:</p> <ul> <li> <p> <code>AmazonEmr</code> - Infers that Amazon EMR
   * might be running on the instances.</p> </li> <li> <p>
   * <code>ApacheCassandra</code> - Infers that Apache Cassandra might be running on
   * the instances.</p> </li> <li> <p> <code>ApacheHadoop</code> - Infers that Apache
   * Hadoop might be running on the instances.</p> </li> <li> <p>
   * <code>Memcached</code> - Infers that Memcached might be running on the
   * instances.</p> </li> <li> <p> <code>NGINX</code> - Infers that NGINX might be
   * running on the instances.</p> </li> <li> <p> <code>PostgreSql</code> - Infers
   * that PostgreSQL might be running on the instances.</p> </li> <li> <p>
   * <code>Redis</code> - Infers that Redis might be running on the instances.</p>
   * </li> <li> <p> <code>Kafka</code> - Infers that Kafka might be running on the
   * instance.</p> </li> <li> <p> <code>SQLServer</code> - Infers that SQLServer
   * might be running on the instance.</p> </li> </ul>
   */
  inline const Aws::Vector<InferredWorkloadType>& GetInferredWorkloadTypes() const { return m_inferredWorkloadTypes; }
  inline bool InferredWorkloadTypesHasBeenSet() const { return m_inferredWorkloadTypesHasBeenSet; }
  template <typename InferredWorkloadTypesT = Aws::Vector<InferredWorkloadType>>
  void SetInferredWorkloadTypes(InferredWorkloadTypesT&& value) {
    m_inferredWorkloadTypesHasBeenSet = true;
    m_inferredWorkloadTypes = std::forward<InferredWorkloadTypesT>(value);
  }
  template <typename InferredWorkloadTypesT = Aws::Vector<InferredWorkloadType>>
  AutoScalingGroupRecommendation& WithInferredWorkloadTypes(InferredWorkloadTypesT&& value) {
    SetInferredWorkloadTypes(std::forward<InferredWorkloadTypesT>(value));
    return *this;
  }
  inline AutoScalingGroupRecommendation& AddInferredWorkloadTypes(InferredWorkloadType value) {
    m_inferredWorkloadTypesHasBeenSet = true;
    m_inferredWorkloadTypes.push_back(value);
    return *this;
  }
  ///@}
 private:
  Aws::String m_accountId;

  Aws::String m_autoScalingGroupArn;

  Aws::String m_autoScalingGroupName;

  Finding m_finding{Finding::NOT_SET};

  Aws::Vector<UtilizationMetric> m_utilizationMetrics;

  double m_lookBackPeriodInDays{0.0};

  AutoScalingGroupConfiguration m_currentConfiguration;

  GpuInfo m_currentInstanceGpuInfo;

  Aws::Vector<AutoScalingGroupRecommendationOption> m_recommendationOptions;

  Aws::Utils::DateTime m_lastRefreshTimestamp{};

  CurrentPerformanceRisk m_currentPerformanceRisk{CurrentPerformanceRisk::NOT_SET};

  EffectiveRecommendationPreferences m_effectiveRecommendationPreferences;

  Aws::Vector<InferredWorkloadType> m_inferredWorkloadTypes;
  bool m_accountIdHasBeenSet = false;
  bool m_autoScalingGroupArnHasBeenSet = false;
  bool m_autoScalingGroupNameHasBeenSet = false;
  bool m_findingHasBeenSet = false;
  bool m_utilizationMetricsHasBeenSet = false;
  bool m_lookBackPeriodInDaysHasBeenSet = false;
  bool m_currentConfigurationHasBeenSet = false;
  bool m_currentInstanceGpuInfoHasBeenSet = false;
  bool m_recommendationOptionsHasBeenSet = false;
  bool m_lastRefreshTimestampHasBeenSet = false;
  bool m_currentPerformanceRiskHasBeenSet = false;
  bool m_effectiveRecommendationPreferencesHasBeenSet = false;
  bool m_inferredWorkloadTypesHasBeenSet = false;
};

}  // namespace Model
}  // namespace ComputeOptimizer
}  // namespace Aws
