/**
 * 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/AWSMap.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/core/utils/memory/stl/AWSVector.h>
#include <aws/ssm/SSM_EXPORTS.h>
#include <aws/ssm/model/AssociationComplianceSeverity.h>
#include <aws/ssm/model/AssociationSyncCompliance.h>
#include <aws/ssm/model/InstanceAssociationOutputLocation.h>
#include <aws/ssm/model/Target.h>
#include <aws/ssm/model/TargetLocation.h>

#include <utility>

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

/**
 * <p>Information about the association version.</p><p><h3>See Also:</h3>   <a
 * href="http://docs.aws.amazon.com/goto/WebAPI/ssm-2014-11-06/AssociationVersionInfo">AWS
 * API Reference</a></p>
 */
class AssociationVersionInfo {
 public:
  AWS_SSM_API AssociationVersionInfo() = default;
  AWS_SSM_API AssociationVersionInfo(Aws::Utils::Json::JsonView jsonValue);
  AWS_SSM_API AssociationVersionInfo& operator=(Aws::Utils::Json::JsonView jsonValue);
  AWS_SSM_API Aws::Utils::Json::JsonValue Jsonize() const;

  ///@{
  /**
   * <p>The ID created by the system when the association was created.</p>
   */
  inline const Aws::String& GetAssociationId() const { return m_associationId; }
  inline bool AssociationIdHasBeenSet() const { return m_associationIdHasBeenSet; }
  template <typename AssociationIdT = Aws::String>
  void SetAssociationId(AssociationIdT&& value) {
    m_associationIdHasBeenSet = true;
    m_associationId = std::forward<AssociationIdT>(value);
  }
  template <typename AssociationIdT = Aws::String>
  AssociationVersionInfo& WithAssociationId(AssociationIdT&& value) {
    SetAssociationId(std::forward<AssociationIdT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The association version.</p>
   */
  inline const Aws::String& GetAssociationVersion() const { return m_associationVersion; }
  inline bool AssociationVersionHasBeenSet() const { return m_associationVersionHasBeenSet; }
  template <typename AssociationVersionT = Aws::String>
  void SetAssociationVersion(AssociationVersionT&& value) {
    m_associationVersionHasBeenSet = true;
    m_associationVersion = std::forward<AssociationVersionT>(value);
  }
  template <typename AssociationVersionT = Aws::String>
  AssociationVersionInfo& WithAssociationVersion(AssociationVersionT&& value) {
    SetAssociationVersion(std::forward<AssociationVersionT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The date the association version was created.</p>
   */
  inline const Aws::Utils::DateTime& GetCreatedDate() const { return m_createdDate; }
  inline bool CreatedDateHasBeenSet() const { return m_createdDateHasBeenSet; }
  template <typename CreatedDateT = Aws::Utils::DateTime>
  void SetCreatedDate(CreatedDateT&& value) {
    m_createdDateHasBeenSet = true;
    m_createdDate = std::forward<CreatedDateT>(value);
  }
  template <typename CreatedDateT = Aws::Utils::DateTime>
  AssociationVersionInfo& WithCreatedDate(CreatedDateT&& value) {
    SetCreatedDate(std::forward<CreatedDateT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The name specified when the association was created.</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>
  AssociationVersionInfo& WithName(NameT&& value) {
    SetName(std::forward<NameT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The version of an Amazon Web Services Systems Manager document (SSM document)
   * used when the association version was created.</p>
   */
  inline const Aws::String& GetDocumentVersion() const { return m_documentVersion; }
  inline bool DocumentVersionHasBeenSet() const { return m_documentVersionHasBeenSet; }
  template <typename DocumentVersionT = Aws::String>
  void SetDocumentVersion(DocumentVersionT&& value) {
    m_documentVersionHasBeenSet = true;
    m_documentVersion = std::forward<DocumentVersionT>(value);
  }
  template <typename DocumentVersionT = Aws::String>
  AssociationVersionInfo& WithDocumentVersion(DocumentVersionT&& value) {
    SetDocumentVersion(std::forward<DocumentVersionT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>Parameters specified when the association version was created.</p>
   */
  inline const Aws::Map<Aws::String, Aws::Vector<Aws::String>>& GetParameters() const { return m_parameters; }
  inline bool ParametersHasBeenSet() const { return m_parametersHasBeenSet; }
  template <typename ParametersT = Aws::Map<Aws::String, Aws::Vector<Aws::String>>>
  void SetParameters(ParametersT&& value) {
    m_parametersHasBeenSet = true;
    m_parameters = std::forward<ParametersT>(value);
  }
  template <typename ParametersT = Aws::Map<Aws::String, Aws::Vector<Aws::String>>>
  AssociationVersionInfo& WithParameters(ParametersT&& value) {
    SetParameters(std::forward<ParametersT>(value));
    return *this;
  }
  template <typename ParametersKeyT = Aws::String, typename ParametersValueT = Aws::Vector<Aws::String>>
  AssociationVersionInfo& AddParameters(ParametersKeyT&& key, ParametersValueT&& value) {
    m_parametersHasBeenSet = true;
    m_parameters.emplace(std::forward<ParametersKeyT>(key), std::forward<ParametersValueT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The targets specified for the association when the association version was
   * created. </p>
   */
  inline const Aws::Vector<Target>& GetTargets() const { return m_targets; }
  inline bool TargetsHasBeenSet() const { return m_targetsHasBeenSet; }
  template <typename TargetsT = Aws::Vector<Target>>
  void SetTargets(TargetsT&& value) {
    m_targetsHasBeenSet = true;
    m_targets = std::forward<TargetsT>(value);
  }
  template <typename TargetsT = Aws::Vector<Target>>
  AssociationVersionInfo& WithTargets(TargetsT&& value) {
    SetTargets(std::forward<TargetsT>(value));
    return *this;
  }
  template <typename TargetsT = Target>
  AssociationVersionInfo& AddTargets(TargetsT&& value) {
    m_targetsHasBeenSet = true;
    m_targets.emplace_back(std::forward<TargetsT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The cron or rate schedule specified for the association when the association
   * version was created.</p>
   */
  inline const Aws::String& GetScheduleExpression() const { return m_scheduleExpression; }
  inline bool ScheduleExpressionHasBeenSet() const { return m_scheduleExpressionHasBeenSet; }
  template <typename ScheduleExpressionT = Aws::String>
  void SetScheduleExpression(ScheduleExpressionT&& value) {
    m_scheduleExpressionHasBeenSet = true;
    m_scheduleExpression = std::forward<ScheduleExpressionT>(value);
  }
  template <typename ScheduleExpressionT = Aws::String>
  AssociationVersionInfo& WithScheduleExpression(ScheduleExpressionT&& value) {
    SetScheduleExpression(std::forward<ScheduleExpressionT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The location in Amazon S3 specified for the association when the association
   * version was created.</p>
   */
  inline const InstanceAssociationOutputLocation& GetOutputLocation() const { return m_outputLocation; }
  inline bool OutputLocationHasBeenSet() const { return m_outputLocationHasBeenSet; }
  template <typename OutputLocationT = InstanceAssociationOutputLocation>
  void SetOutputLocation(OutputLocationT&& value) {
    m_outputLocationHasBeenSet = true;
    m_outputLocation = std::forward<OutputLocationT>(value);
  }
  template <typename OutputLocationT = InstanceAssociationOutputLocation>
  AssociationVersionInfo& WithOutputLocation(OutputLocationT&& value) {
    SetOutputLocation(std::forward<OutputLocationT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The name specified for the association version when the association version
   * was created.</p>
   */
  inline const Aws::String& GetAssociationName() const { return m_associationName; }
  inline bool AssociationNameHasBeenSet() const { return m_associationNameHasBeenSet; }
  template <typename AssociationNameT = Aws::String>
  void SetAssociationName(AssociationNameT&& value) {
    m_associationNameHasBeenSet = true;
    m_associationName = std::forward<AssociationNameT>(value);
  }
  template <typename AssociationNameT = Aws::String>
  AssociationVersionInfo& WithAssociationName(AssociationNameT&& value) {
    SetAssociationName(std::forward<AssociationNameT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The number of errors that are allowed before the system stops sending
   * requests to run the association on additional targets. You can specify either an
   * absolute number of errors, for example 10, or a percentage of the target set,
   * for example 10%. If you specify 3, for example, the system stops sending
   * requests when the fourth error is received. If you specify 0, then the system
   * stops sending requests after the first error is returned. If you run an
   * association on 50 managed nodes and set <code>MaxError</code> to 10%, then the
   * system stops sending the request when the sixth error is received.</p>
   * <p>Executions that are already running an association when
   * <code>MaxErrors</code> is reached are allowed to complete, but some of these
   * executions may fail as well. If you need to ensure that there won't be more than
   * max-errors failed executions, set <code>MaxConcurrency</code> to 1 so that
   * executions proceed one at a time.</p>
   */
  inline const Aws::String& GetMaxErrors() const { return m_maxErrors; }
  inline bool MaxErrorsHasBeenSet() const { return m_maxErrorsHasBeenSet; }
  template <typename MaxErrorsT = Aws::String>
  void SetMaxErrors(MaxErrorsT&& value) {
    m_maxErrorsHasBeenSet = true;
    m_maxErrors = std::forward<MaxErrorsT>(value);
  }
  template <typename MaxErrorsT = Aws::String>
  AssociationVersionInfo& WithMaxErrors(MaxErrorsT&& value) {
    SetMaxErrors(std::forward<MaxErrorsT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The maximum number of targets allowed to run the association at the same
   * time. You can specify a number, for example 10, or a percentage of the target
   * set, for example 10%. The default value is 100%, which means all targets run the
   * association at the same time.</p> <p>If a new managed node starts and attempts
   * to run an association while Systems Manager is running
   * <code>MaxConcurrency</code> associations, the association is allowed to run.
   * During the next association interval, the new managed node will process its
   * association within the limit specified for <code>MaxConcurrency</code>.</p>
   */
  inline const Aws::String& GetMaxConcurrency() const { return m_maxConcurrency; }
  inline bool MaxConcurrencyHasBeenSet() const { return m_maxConcurrencyHasBeenSet; }
  template <typename MaxConcurrencyT = Aws::String>
  void SetMaxConcurrency(MaxConcurrencyT&& value) {
    m_maxConcurrencyHasBeenSet = true;
    m_maxConcurrency = std::forward<MaxConcurrencyT>(value);
  }
  template <typename MaxConcurrencyT = Aws::String>
  AssociationVersionInfo& WithMaxConcurrency(MaxConcurrencyT&& value) {
    SetMaxConcurrency(std::forward<MaxConcurrencyT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The severity level that is assigned to the association.</p>
   */
  inline AssociationComplianceSeverity GetComplianceSeverity() const { return m_complianceSeverity; }
  inline bool ComplianceSeverityHasBeenSet() const { return m_complianceSeverityHasBeenSet; }
  inline void SetComplianceSeverity(AssociationComplianceSeverity value) {
    m_complianceSeverityHasBeenSet = true;
    m_complianceSeverity = value;
  }
  inline AssociationVersionInfo& WithComplianceSeverity(AssociationComplianceSeverity value) {
    SetComplianceSeverity(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The mode for generating association compliance. You can specify
   * <code>AUTO</code> or <code>MANUAL</code>. In <code>AUTO</code> mode, the system
   * uses the status of the association execution to determine the compliance status.
   * If the association execution runs successfully, then the association is
   * <code>COMPLIANT</code>. If the association execution doesn't run successfully,
   * the association is <code>NON-COMPLIANT</code>.</p> <p>In <code>MANUAL</code>
   * mode, you must specify the <code>AssociationId</code> as a parameter for the
   * <a>PutComplianceItems</a> API operation. In this case, compliance data isn't
   * managed by State Manager, a tool in Amazon Web Services Systems Manager. It is
   * managed by your direct call to the <a>PutComplianceItems</a> API operation.</p>
   * <p>By default, all associations use <code>AUTO</code> mode.</p>
   */
  inline AssociationSyncCompliance GetSyncCompliance() const { return m_syncCompliance; }
  inline bool SyncComplianceHasBeenSet() const { return m_syncComplianceHasBeenSet; }
  inline void SetSyncCompliance(AssociationSyncCompliance value) {
    m_syncComplianceHasBeenSet = true;
    m_syncCompliance = value;
  }
  inline AssociationVersionInfo& WithSyncCompliance(AssociationSyncCompliance value) {
    SetSyncCompliance(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>By default, when you create new associations, the system runs it immediately
   * after it is created and then according to the schedule you specified. Specify
   * this option if you don't want an association to run immediately after you create
   * it. This parameter isn't supported for rate expressions.</p>
   */
  inline bool GetApplyOnlyAtCronInterval() const { return m_applyOnlyAtCronInterval; }
  inline bool ApplyOnlyAtCronIntervalHasBeenSet() const { return m_applyOnlyAtCronIntervalHasBeenSet; }
  inline void SetApplyOnlyAtCronInterval(bool value) {
    m_applyOnlyAtCronIntervalHasBeenSet = true;
    m_applyOnlyAtCronInterval = value;
  }
  inline AssociationVersionInfo& WithApplyOnlyAtCronInterval(bool value) {
    SetApplyOnlyAtCronInterval(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The names or Amazon Resource Names (ARNs) of the Change Calendar type
   * documents your associations are gated under. The associations for this version
   * only run when that Change Calendar is open. For more information, see <a
   * href="https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-change-calendar">Amazon
   * Web Services Systems Manager Change Calendar</a> in the <i>Amazon Web Services
   * Systems Manager User Guide</i>.</p>
   */
  inline const Aws::Vector<Aws::String>& GetCalendarNames() const { return m_calendarNames; }
  inline bool CalendarNamesHasBeenSet() const { return m_calendarNamesHasBeenSet; }
  template <typename CalendarNamesT = Aws::Vector<Aws::String>>
  void SetCalendarNames(CalendarNamesT&& value) {
    m_calendarNamesHasBeenSet = true;
    m_calendarNames = std::forward<CalendarNamesT>(value);
  }
  template <typename CalendarNamesT = Aws::Vector<Aws::String>>
  AssociationVersionInfo& WithCalendarNames(CalendarNamesT&& value) {
    SetCalendarNames(std::forward<CalendarNamesT>(value));
    return *this;
  }
  template <typename CalendarNamesT = Aws::String>
  AssociationVersionInfo& AddCalendarNames(CalendarNamesT&& value) {
    m_calendarNamesHasBeenSet = true;
    m_calendarNames.emplace_back(std::forward<CalendarNamesT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The combination of Amazon Web Services Regions and Amazon Web Services
   * accounts where you wanted to run the association when this association version
   * was created.</p>
   */
  inline const Aws::Vector<TargetLocation>& GetTargetLocations() const { return m_targetLocations; }
  inline bool TargetLocationsHasBeenSet() const { return m_targetLocationsHasBeenSet; }
  template <typename TargetLocationsT = Aws::Vector<TargetLocation>>
  void SetTargetLocations(TargetLocationsT&& value) {
    m_targetLocationsHasBeenSet = true;
    m_targetLocations = std::forward<TargetLocationsT>(value);
  }
  template <typename TargetLocationsT = Aws::Vector<TargetLocation>>
  AssociationVersionInfo& WithTargetLocations(TargetLocationsT&& value) {
    SetTargetLocations(std::forward<TargetLocationsT>(value));
    return *this;
  }
  template <typename TargetLocationsT = TargetLocation>
  AssociationVersionInfo& AddTargetLocations(TargetLocationsT&& value) {
    m_targetLocationsHasBeenSet = true;
    m_targetLocations.emplace_back(std::forward<TargetLocationsT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>Number of days to wait after the scheduled day to run an association.</p>
   */
  inline int GetScheduleOffset() const { return m_scheduleOffset; }
  inline bool ScheduleOffsetHasBeenSet() const { return m_scheduleOffsetHasBeenSet; }
  inline void SetScheduleOffset(int value) {
    m_scheduleOffsetHasBeenSet = true;
    m_scheduleOffset = value;
  }
  inline AssociationVersionInfo& WithScheduleOffset(int value) {
    SetScheduleOffset(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The number of hours that an association can run on specified targets. After
   * the resulting cutoff time passes, associations that are currently running are
   * cancelled, and no pending executions are started on remaining targets.</p>
   */
  inline int GetDuration() const { return m_duration; }
  inline bool DurationHasBeenSet() const { return m_durationHasBeenSet; }
  inline void SetDuration(int value) {
    m_durationHasBeenSet = true;
    m_duration = value;
  }
  inline AssociationVersionInfo& WithDuration(int value) {
    SetDuration(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>A key-value mapping of document parameters to target resources. Both Targets
   * and TargetMaps can't be specified together.</p>
   */
  inline const Aws::Vector<Aws::Map<Aws::String, Aws::Vector<Aws::String>>>& GetTargetMaps() const { return m_targetMaps; }
  inline bool TargetMapsHasBeenSet() const { return m_targetMapsHasBeenSet; }
  template <typename TargetMapsT = Aws::Vector<Aws::Map<Aws::String, Aws::Vector<Aws::String>>>>
  void SetTargetMaps(TargetMapsT&& value) {
    m_targetMapsHasBeenSet = true;
    m_targetMaps = std::forward<TargetMapsT>(value);
  }
  template <typename TargetMapsT = Aws::Vector<Aws::Map<Aws::String, Aws::Vector<Aws::String>>>>
  AssociationVersionInfo& WithTargetMaps(TargetMapsT&& value) {
    SetTargetMaps(std::forward<TargetMapsT>(value));
    return *this;
  }
  template <typename TargetMapsT = Aws::Map<Aws::String, Aws::Vector<Aws::String>>>
  AssociationVersionInfo& AddTargetMaps(TargetMapsT&& value) {
    m_targetMapsHasBeenSet = true;
    m_targetMaps.emplace_back(std::forward<TargetMapsT>(value));
    return *this;
  }
  ///@}
 private:
  Aws::String m_associationId;

  Aws::String m_associationVersion;

  Aws::Utils::DateTime m_createdDate{};

  Aws::String m_name;

  Aws::String m_documentVersion;

  Aws::Map<Aws::String, Aws::Vector<Aws::String>> m_parameters;

  Aws::Vector<Target> m_targets;

  Aws::String m_scheduleExpression;

  InstanceAssociationOutputLocation m_outputLocation;

  Aws::String m_associationName;

  Aws::String m_maxErrors;

  Aws::String m_maxConcurrency;

  AssociationComplianceSeverity m_complianceSeverity{AssociationComplianceSeverity::NOT_SET};

  AssociationSyncCompliance m_syncCompliance{AssociationSyncCompliance::NOT_SET};

  bool m_applyOnlyAtCronInterval{false};

  Aws::Vector<Aws::String> m_calendarNames;

  Aws::Vector<TargetLocation> m_targetLocations;

  int m_scheduleOffset{0};

  int m_duration{0};

  Aws::Vector<Aws::Map<Aws::String, Aws::Vector<Aws::String>>> m_targetMaps;
  bool m_associationIdHasBeenSet = false;
  bool m_associationVersionHasBeenSet = false;
  bool m_createdDateHasBeenSet = false;
  bool m_nameHasBeenSet = false;
  bool m_documentVersionHasBeenSet = false;
  bool m_parametersHasBeenSet = false;
  bool m_targetsHasBeenSet = false;
  bool m_scheduleExpressionHasBeenSet = false;
  bool m_outputLocationHasBeenSet = false;
  bool m_associationNameHasBeenSet = false;
  bool m_maxErrorsHasBeenSet = false;
  bool m_maxConcurrencyHasBeenSet = false;
  bool m_complianceSeverityHasBeenSet = false;
  bool m_syncComplianceHasBeenSet = false;
  bool m_applyOnlyAtCronIntervalHasBeenSet = false;
  bool m_calendarNamesHasBeenSet = false;
  bool m_targetLocationsHasBeenSet = false;
  bool m_scheduleOffsetHasBeenSet = false;
  bool m_durationHasBeenSet = false;
  bool m_targetMapsHasBeenSet = false;
};

}  // namespace Model
}  // namespace SSM
}  // namespace Aws
