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

#pragma once
#include <aws/core/utils/DateTime.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/core/utils/memory/stl/AWSVector.h>
#include <aws/trustedadvisor/TrustedAdvisor_EXPORTS.h>
#include <aws/trustedadvisor/model/RecommendationLifecycleStage.h>
#include <aws/trustedadvisor/model/RecommendationPillar.h>
#include <aws/trustedadvisor/model/RecommendationPillarSpecificAggregates.h>
#include <aws/trustedadvisor/model/RecommendationResourcesAggregates.h>
#include <aws/trustedadvisor/model/RecommendationSource.h>
#include <aws/trustedadvisor/model/RecommendationStatus.h>
#include <aws/trustedadvisor/model/RecommendationType.h>
#include <aws/trustedadvisor/model/UpdateRecommendationLifecycleStageReasonCode.h>

#include <utility>

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

/**
 * <p>A Recommendation for an Account</p><p><h3>See Also:</h3>   <a
 * href="http://docs.aws.amazon.com/goto/WebAPI/trustedadvisor-2022-09-15/Recommendation">AWS
 * API Reference</a></p>
 */
class Recommendation {
 public:
  AWS_TRUSTEDADVISOR_API Recommendation() = default;
  AWS_TRUSTEDADVISOR_API Recommendation(Aws::Utils::Json::JsonView jsonValue);
  AWS_TRUSTEDADVISOR_API Recommendation& operator=(Aws::Utils::Json::JsonView jsonValue);
  AWS_TRUSTEDADVISOR_API Aws::Utils::Json::JsonValue Jsonize() const;

  ///@{
  /**
   * <p>The ARN of the Recommendation</p>
   */
  inline const Aws::String& GetArn() const { return m_arn; }
  inline bool ArnHasBeenSet() const { return m_arnHasBeenSet; }
  template <typename ArnT = Aws::String>
  void SetArn(ArnT&& value) {
    m_arnHasBeenSet = true;
    m_arn = std::forward<ArnT>(value);
  }
  template <typename ArnT = Aws::String>
  Recommendation& WithArn(ArnT&& value) {
    SetArn(std::forward<ArnT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The AWS Services that the Recommendation applies to</p>
   */
  inline const Aws::Vector<Aws::String>& GetAwsServices() const { return m_awsServices; }
  inline bool AwsServicesHasBeenSet() const { return m_awsServicesHasBeenSet; }
  template <typename AwsServicesT = Aws::Vector<Aws::String>>
  void SetAwsServices(AwsServicesT&& value) {
    m_awsServicesHasBeenSet = true;
    m_awsServices = std::forward<AwsServicesT>(value);
  }
  template <typename AwsServicesT = Aws::Vector<Aws::String>>
  Recommendation& WithAwsServices(AwsServicesT&& value) {
    SetAwsServices(std::forward<AwsServicesT>(value));
    return *this;
  }
  template <typename AwsServicesT = Aws::String>
  Recommendation& AddAwsServices(AwsServicesT&& value) {
    m_awsServicesHasBeenSet = true;
    m_awsServices.emplace_back(std::forward<AwsServicesT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The AWS Trusted Advisor Check ARN that relates to the Recommendation</p>
   */
  inline const Aws::String& GetCheckArn() const { return m_checkArn; }
  inline bool CheckArnHasBeenSet() const { return m_checkArnHasBeenSet; }
  template <typename CheckArnT = Aws::String>
  void SetCheckArn(CheckArnT&& value) {
    m_checkArnHasBeenSet = true;
    m_checkArn = std::forward<CheckArnT>(value);
  }
  template <typename CheckArnT = Aws::String>
  Recommendation& WithCheckArn(CheckArnT&& value) {
    SetCheckArn(std::forward<CheckArnT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>When the Recommendation was created, if created by AWS Trusted Advisor
   * Priority</p>
   */
  inline const Aws::Utils::DateTime& GetCreatedAt() const { return m_createdAt; }
  inline bool CreatedAtHasBeenSet() const { return m_createdAtHasBeenSet; }
  template <typename CreatedAtT = Aws::Utils::DateTime>
  void SetCreatedAt(CreatedAtT&& value) {
    m_createdAtHasBeenSet = true;
    m_createdAt = std::forward<CreatedAtT>(value);
  }
  template <typename CreatedAtT = Aws::Utils::DateTime>
  Recommendation& WithCreatedAt(CreatedAtT&& value) {
    SetCreatedAt(std::forward<CreatedAtT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The creator, if created by AWS Trusted Advisor Priority</p>
   */
  inline const Aws::String& GetCreatedBy() const { return m_createdBy; }
  inline bool CreatedByHasBeenSet() const { return m_createdByHasBeenSet; }
  template <typename CreatedByT = Aws::String>
  void SetCreatedBy(CreatedByT&& value) {
    m_createdByHasBeenSet = true;
    m_createdBy = std::forward<CreatedByT>(value);
  }
  template <typename CreatedByT = Aws::String>
  Recommendation& WithCreatedBy(CreatedByT&& value) {
    SetCreatedBy(std::forward<CreatedByT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>A description for AWS Trusted Advisor recommendations</p>
   */
  inline const Aws::String& GetDescription() const { return m_description; }
  inline bool DescriptionHasBeenSet() const { return m_descriptionHasBeenSet; }
  template <typename DescriptionT = Aws::String>
  void SetDescription(DescriptionT&& value) {
    m_descriptionHasBeenSet = true;
    m_description = std::forward<DescriptionT>(value);
  }
  template <typename DescriptionT = Aws::String>
  Recommendation& WithDescription(DescriptionT&& value) {
    SetDescription(std::forward<DescriptionT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The ID which identifies where the Recommendation was produced</p>
   */
  inline const Aws::String& GetId() const { return m_id; }
  inline bool IdHasBeenSet() const { return m_idHasBeenSet; }
  template <typename IdT = Aws::String>
  void SetId(IdT&& value) {
    m_idHasBeenSet = true;
    m_id = std::forward<IdT>(value);
  }
  template <typename IdT = Aws::String>
  Recommendation& WithId(IdT&& value) {
    SetId(std::forward<IdT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>When the Recommendation was last updated</p>
   */
  inline const Aws::Utils::DateTime& GetLastUpdatedAt() const { return m_lastUpdatedAt; }
  inline bool LastUpdatedAtHasBeenSet() const { return m_lastUpdatedAtHasBeenSet; }
  template <typename LastUpdatedAtT = Aws::Utils::DateTime>
  void SetLastUpdatedAt(LastUpdatedAtT&& value) {
    m_lastUpdatedAtHasBeenSet = true;
    m_lastUpdatedAt = std::forward<LastUpdatedAtT>(value);
  }
  template <typename LastUpdatedAtT = Aws::Utils::DateTime>
  Recommendation& WithLastUpdatedAt(LastUpdatedAtT&& value) {
    SetLastUpdatedAt(std::forward<LastUpdatedAtT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The lifecycle stage from AWS Trusted Advisor Priority</p>
   */
  inline RecommendationLifecycleStage GetLifecycleStage() const { return m_lifecycleStage; }
  inline bool LifecycleStageHasBeenSet() const { return m_lifecycleStageHasBeenSet; }
  inline void SetLifecycleStage(RecommendationLifecycleStage value) {
    m_lifecycleStageHasBeenSet = true;
    m_lifecycleStage = value;
  }
  inline Recommendation& WithLifecycleStage(RecommendationLifecycleStage value) {
    SetLifecycleStage(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The name of the AWS Trusted Advisor Recommendation</p>
   */
  inline const Aws::String& GetName() const { return m_name; }
  inline bool NameHasBeenSet() const { return m_nameHasBeenSet; }
  template <typename NameT = Aws::String>
  void SetName(NameT&& value) {
    m_nameHasBeenSet = true;
    m_name = std::forward<NameT>(value);
  }
  template <typename NameT = Aws::String>
  Recommendation& WithName(NameT&& value) {
    SetName(std::forward<NameT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The pillar aggregations for cost savings</p>
   */
  inline const RecommendationPillarSpecificAggregates& GetPillarSpecificAggregates() const { return m_pillarSpecificAggregates; }
  inline bool PillarSpecificAggregatesHasBeenSet() const { return m_pillarSpecificAggregatesHasBeenSet; }
  template <typename PillarSpecificAggregatesT = RecommendationPillarSpecificAggregates>
  void SetPillarSpecificAggregates(PillarSpecificAggregatesT&& value) {
    m_pillarSpecificAggregatesHasBeenSet = true;
    m_pillarSpecificAggregates = std::forward<PillarSpecificAggregatesT>(value);
  }
  template <typename PillarSpecificAggregatesT = RecommendationPillarSpecificAggregates>
  Recommendation& WithPillarSpecificAggregates(PillarSpecificAggregatesT&& value) {
    SetPillarSpecificAggregates(std::forward<PillarSpecificAggregatesT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The Pillars that the Recommendation is optimizing</p>
   */
  inline const Aws::Vector<RecommendationPillar>& GetPillars() const { return m_pillars; }
  inline bool PillarsHasBeenSet() const { return m_pillarsHasBeenSet; }
  template <typename PillarsT = Aws::Vector<RecommendationPillar>>
  void SetPillars(PillarsT&& value) {
    m_pillarsHasBeenSet = true;
    m_pillars = std::forward<PillarsT>(value);
  }
  template <typename PillarsT = Aws::Vector<RecommendationPillar>>
  Recommendation& WithPillars(PillarsT&& value) {
    SetPillars(std::forward<PillarsT>(value));
    return *this;
  }
  inline Recommendation& AddPillars(RecommendationPillar value) {
    m_pillarsHasBeenSet = true;
    m_pillars.push_back(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>When the Recommendation was resolved</p>
   */
  inline const Aws::Utils::DateTime& GetResolvedAt() const { return m_resolvedAt; }
  inline bool ResolvedAtHasBeenSet() const { return m_resolvedAtHasBeenSet; }
  template <typename ResolvedAtT = Aws::Utils::DateTime>
  void SetResolvedAt(ResolvedAtT&& value) {
    m_resolvedAtHasBeenSet = true;
    m_resolvedAt = std::forward<ResolvedAtT>(value);
  }
  template <typename ResolvedAtT = Aws::Utils::DateTime>
  Recommendation& WithResolvedAt(ResolvedAtT&& value) {
    SetResolvedAt(std::forward<ResolvedAtT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>An aggregation of all resources</p>
   */
  inline const RecommendationResourcesAggregates& GetResourcesAggregates() const { return m_resourcesAggregates; }
  inline bool ResourcesAggregatesHasBeenSet() const { return m_resourcesAggregatesHasBeenSet; }
  template <typename ResourcesAggregatesT = RecommendationResourcesAggregates>
  void SetResourcesAggregates(ResourcesAggregatesT&& value) {
    m_resourcesAggregatesHasBeenSet = true;
    m_resourcesAggregates = std::forward<ResourcesAggregatesT>(value);
  }
  template <typename ResourcesAggregatesT = RecommendationResourcesAggregates>
  Recommendation& WithResourcesAggregates(ResourcesAggregatesT&& value) {
    SetResourcesAggregates(std::forward<ResourcesAggregatesT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The source of the Recommendation</p>
   */
  inline RecommendationSource GetSource() const { return m_source; }
  inline bool SourceHasBeenSet() const { return m_sourceHasBeenSet; }
  inline void SetSource(RecommendationSource value) {
    m_sourceHasBeenSet = true;
    m_source = value;
  }
  inline Recommendation& WithSource(RecommendationSource value) {
    SetSource(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The status of the Recommendation</p>
   */
  inline RecommendationStatus GetStatus() const { return m_status; }
  inline bool StatusHasBeenSet() const { return m_statusHasBeenSet; }
  inline void SetStatus(RecommendationStatus value) {
    m_statusHasBeenSet = true;
    m_status = value;
  }
  inline Recommendation& WithStatus(RecommendationStatus value) {
    SetStatus(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>Whether the Recommendation was automated or generated by AWS Trusted Advisor
   * Priority</p>
   */
  inline RecommendationType GetType() const { return m_type; }
  inline bool TypeHasBeenSet() const { return m_typeHasBeenSet; }
  inline void SetType(RecommendationType value) {
    m_typeHasBeenSet = true;
    m_type = value;
  }
  inline Recommendation& WithType(RecommendationType value) {
    SetType(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>Reason for the lifecycle stage change</p>
   */
  inline const Aws::String& GetUpdateReason() const { return m_updateReason; }
  inline bool UpdateReasonHasBeenSet() const { return m_updateReasonHasBeenSet; }
  template <typename UpdateReasonT = Aws::String>
  void SetUpdateReason(UpdateReasonT&& value) {
    m_updateReasonHasBeenSet = true;
    m_updateReason = std::forward<UpdateReasonT>(value);
  }
  template <typename UpdateReasonT = Aws::String>
  Recommendation& WithUpdateReason(UpdateReasonT&& value) {
    SetUpdateReason(std::forward<UpdateReasonT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>Reason code for the lifecycle state change</p>
   */
  inline UpdateRecommendationLifecycleStageReasonCode GetUpdateReasonCode() const { return m_updateReasonCode; }
  inline bool UpdateReasonCodeHasBeenSet() const { return m_updateReasonCodeHasBeenSet; }
  inline void SetUpdateReasonCode(UpdateRecommendationLifecycleStageReasonCode value) {
    m_updateReasonCodeHasBeenSet = true;
    m_updateReasonCode = value;
  }
  inline Recommendation& WithUpdateReasonCode(UpdateRecommendationLifecycleStageReasonCode value) {
    SetUpdateReasonCode(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The person on whose behalf a Technical Account Manager (TAM) updated the
   * recommendation. This information is only available when a Technical Account
   * Manager takes an action on a recommendation managed by AWS Trusted Advisor
   * Priority </p>
   */
  inline const Aws::String& GetUpdatedOnBehalfOf() const { return m_updatedOnBehalfOf; }
  inline bool UpdatedOnBehalfOfHasBeenSet() const { return m_updatedOnBehalfOfHasBeenSet; }
  template <typename UpdatedOnBehalfOfT = Aws::String>
  void SetUpdatedOnBehalfOf(UpdatedOnBehalfOfT&& value) {
    m_updatedOnBehalfOfHasBeenSet = true;
    m_updatedOnBehalfOf = std::forward<UpdatedOnBehalfOfT>(value);
  }
  template <typename UpdatedOnBehalfOfT = Aws::String>
  Recommendation& WithUpdatedOnBehalfOf(UpdatedOnBehalfOfT&& value) {
    SetUpdatedOnBehalfOf(std::forward<UpdatedOnBehalfOfT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The job title of the person on whose behalf a Technical Account Manager (TAM)
   * updated the recommendation. This information is only available when a Technical
   * Account Manager takes an action on a recommendation managed by AWS Trusted
   * Advisor Priority </p>
   */
  inline const Aws::String& GetUpdatedOnBehalfOfJobTitle() const { return m_updatedOnBehalfOfJobTitle; }
  inline bool UpdatedOnBehalfOfJobTitleHasBeenSet() const { return m_updatedOnBehalfOfJobTitleHasBeenSet; }
  template <typename UpdatedOnBehalfOfJobTitleT = Aws::String>
  void SetUpdatedOnBehalfOfJobTitle(UpdatedOnBehalfOfJobTitleT&& value) {
    m_updatedOnBehalfOfJobTitleHasBeenSet = true;
    m_updatedOnBehalfOfJobTitle = std::forward<UpdatedOnBehalfOfJobTitleT>(value);
  }
  template <typename UpdatedOnBehalfOfJobTitleT = Aws::String>
  Recommendation& WithUpdatedOnBehalfOfJobTitle(UpdatedOnBehalfOfJobTitleT&& value) {
    SetUpdatedOnBehalfOfJobTitle(std::forward<UpdatedOnBehalfOfJobTitleT>(value));
    return *this;
  }
  ///@}
 private:
  Aws::String m_arn;

  Aws::Vector<Aws::String> m_awsServices;

  Aws::String m_checkArn;

  Aws::Utils::DateTime m_createdAt{};

  Aws::String m_createdBy;

  Aws::String m_description;

  Aws::String m_id;

  Aws::Utils::DateTime m_lastUpdatedAt{};

  RecommendationLifecycleStage m_lifecycleStage{RecommendationLifecycleStage::NOT_SET};

  Aws::String m_name;

  RecommendationPillarSpecificAggregates m_pillarSpecificAggregates;

  Aws::Vector<RecommendationPillar> m_pillars;

  Aws::Utils::DateTime m_resolvedAt{};

  RecommendationResourcesAggregates m_resourcesAggregates;

  RecommendationSource m_source{RecommendationSource::NOT_SET};

  RecommendationStatus m_status{RecommendationStatus::NOT_SET};

  RecommendationType m_type{RecommendationType::NOT_SET};

  Aws::String m_updateReason;

  UpdateRecommendationLifecycleStageReasonCode m_updateReasonCode{UpdateRecommendationLifecycleStageReasonCode::NOT_SET};

  Aws::String m_updatedOnBehalfOf;

  Aws::String m_updatedOnBehalfOfJobTitle;
  bool m_arnHasBeenSet = false;
  bool m_awsServicesHasBeenSet = false;
  bool m_checkArnHasBeenSet = false;
  bool m_createdAtHasBeenSet = false;
  bool m_createdByHasBeenSet = false;
  bool m_descriptionHasBeenSet = false;
  bool m_idHasBeenSet = false;
  bool m_lastUpdatedAtHasBeenSet = false;
  bool m_lifecycleStageHasBeenSet = false;
  bool m_nameHasBeenSet = false;
  bool m_pillarSpecificAggregatesHasBeenSet = false;
  bool m_pillarsHasBeenSet = false;
  bool m_resolvedAtHasBeenSet = false;
  bool m_resourcesAggregatesHasBeenSet = false;
  bool m_sourceHasBeenSet = false;
  bool m_statusHasBeenSet = false;
  bool m_typeHasBeenSet = false;
  bool m_updateReasonHasBeenSet = false;
  bool m_updateReasonCodeHasBeenSet = false;
  bool m_updatedOnBehalfOfHasBeenSet = false;
  bool m_updatedOnBehalfOfJobTitleHasBeenSet = false;
};

}  // namespace Model
}  // namespace TrustedAdvisor
}  // namespace Aws
