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

#pragma once
#include <aws/core/utils/UUID.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/core/utils/memory/stl/AWSVector.h>
#include <aws/ssm/SSMRequest.h>
#include <aws/ssm/SSM_EXPORTS.h>
#include <aws/ssm/model/Tag.h>

#include <utility>

namespace Aws {
namespace SSM {
namespace Model {

/**
 */
class CreateMaintenanceWindowRequest : public SSMRequest {
 public:
  AWS_SSM_API CreateMaintenanceWindowRequest() = default;

  // Service request name is the Operation name which will send this request out,
  // each operation should has unique request name, so that we can get operation's name from this request.
  // Note: this is not true for response, multiple operations may have the same response name,
  // so we can not get operation's name from response.
  inline virtual const char* GetServiceRequestName() const override { return "CreateMaintenanceWindow"; }

  AWS_SSM_API Aws::String SerializePayload() const override;

  AWS_SSM_API Aws::Http::HeaderValueCollection GetRequestSpecificHeaders() const override;

  ///@{
  /**
   * <p>The name of the maintenance window.</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>
  CreateMaintenanceWindowRequest& WithName(NameT&& value) {
    SetName(std::forward<NameT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>An optional description for the maintenance window. We recommend specifying a
   * description to help you organize your maintenance windows. </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>
  CreateMaintenanceWindowRequest& WithDescription(DescriptionT&& value) {
    SetDescription(std::forward<DescriptionT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The date and time, in ISO-8601 Extended format, for when you want the
   * maintenance window to become active. <code>StartDate</code> allows you to delay
   * activation of the maintenance window until the specified future date.</p>
   * <p>When using a rate schedule, if you provide a start date that occurs in the
   * past, the current date and time are used as the start date. </p>
   */
  inline const Aws::String& GetStartDate() const { return m_startDate; }
  inline bool StartDateHasBeenSet() const { return m_startDateHasBeenSet; }
  template <typename StartDateT = Aws::String>
  void SetStartDate(StartDateT&& value) {
    m_startDateHasBeenSet = true;
    m_startDate = std::forward<StartDateT>(value);
  }
  template <typename StartDateT = Aws::String>
  CreateMaintenanceWindowRequest& WithStartDate(StartDateT&& value) {
    SetStartDate(std::forward<StartDateT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The date and time, in ISO-8601 Extended format, for when you want the
   * maintenance window to become inactive. <code>EndDate</code> allows you to set a
   * date and time in the future when the maintenance window will no longer run.</p>
   */
  inline const Aws::String& GetEndDate() const { return m_endDate; }
  inline bool EndDateHasBeenSet() const { return m_endDateHasBeenSet; }
  template <typename EndDateT = Aws::String>
  void SetEndDate(EndDateT&& value) {
    m_endDateHasBeenSet = true;
    m_endDate = std::forward<EndDateT>(value);
  }
  template <typename EndDateT = Aws::String>
  CreateMaintenanceWindowRequest& WithEndDate(EndDateT&& value) {
    SetEndDate(std::forward<EndDateT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The schedule of the maintenance window in the form of a cron or rate
   * expression.</p>
   */
  inline const Aws::String& GetSchedule() const { return m_schedule; }
  inline bool ScheduleHasBeenSet() const { return m_scheduleHasBeenSet; }
  template <typename ScheduleT = Aws::String>
  void SetSchedule(ScheduleT&& value) {
    m_scheduleHasBeenSet = true;
    m_schedule = std::forward<ScheduleT>(value);
  }
  template <typename ScheduleT = Aws::String>
  CreateMaintenanceWindowRequest& WithSchedule(ScheduleT&& value) {
    SetSchedule(std::forward<ScheduleT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The time zone that the scheduled maintenance window executions are based on,
   * in Internet Assigned Numbers Authority (IANA) format. For example:
   * "America/Los_Angeles", "UTC", or "Asia/Seoul". For more information, see the <a
   * href="https://www.iana.org/time-zones">Time Zone Database</a> on the IANA
   * website.</p>
   */
  inline const Aws::String& GetScheduleTimezone() const { return m_scheduleTimezone; }
  inline bool ScheduleTimezoneHasBeenSet() const { return m_scheduleTimezoneHasBeenSet; }
  template <typename ScheduleTimezoneT = Aws::String>
  void SetScheduleTimezone(ScheduleTimezoneT&& value) {
    m_scheduleTimezoneHasBeenSet = true;
    m_scheduleTimezone = std::forward<ScheduleTimezoneT>(value);
  }
  template <typename ScheduleTimezoneT = Aws::String>
  CreateMaintenanceWindowRequest& WithScheduleTimezone(ScheduleTimezoneT&& value) {
    SetScheduleTimezone(std::forward<ScheduleTimezoneT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The number of days to wait after the date and time specified by a cron
   * expression before running the maintenance window.</p> <p>For example, the
   * following cron expression schedules a maintenance window to run on the third
   * Tuesday of every month at 11:30 PM.</p> <p> <code>cron(30 23 ? * TUE#3 *)</code>
   * </p> <p>If the schedule offset is <code>2</code>, the maintenance window won't
   * run until two days later.</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 CreateMaintenanceWindowRequest& WithScheduleOffset(int value) {
    SetScheduleOffset(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The duration of the maintenance window in hours.</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 CreateMaintenanceWindowRequest& WithDuration(int value) {
    SetDuration(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>The number of hours before the end of the maintenance window that Amazon Web
   * Services Systems Manager stops scheduling new tasks for execution.</p>
   */
  inline int GetCutoff() const { return m_cutoff; }
  inline bool CutoffHasBeenSet() const { return m_cutoffHasBeenSet; }
  inline void SetCutoff(int value) {
    m_cutoffHasBeenSet = true;
    m_cutoff = value;
  }
  inline CreateMaintenanceWindowRequest& WithCutoff(int value) {
    SetCutoff(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>Enables a maintenance window task to run on managed nodes, even if you
   * haven't registered those nodes as targets. If enabled, then you must specify the
   * unregistered managed nodes (by node ID) when you register a task with the
   * maintenance window.</p> <p>If you don't enable this option, then you must
   * specify previously-registered targets when you register a task with the
   * maintenance window.</p>
   */
  inline bool GetAllowUnassociatedTargets() const { return m_allowUnassociatedTargets; }
  inline bool AllowUnassociatedTargetsHasBeenSet() const { return m_allowUnassociatedTargetsHasBeenSet; }
  inline void SetAllowUnassociatedTargets(bool value) {
    m_allowUnassociatedTargetsHasBeenSet = true;
    m_allowUnassociatedTargets = value;
  }
  inline CreateMaintenanceWindowRequest& WithAllowUnassociatedTargets(bool value) {
    SetAllowUnassociatedTargets(value);
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>User-provided idempotency token.</p>
   */
  inline const Aws::String& GetClientToken() const { return m_clientToken; }
  inline bool ClientTokenHasBeenSet() const { return m_clientTokenHasBeenSet; }
  template <typename ClientTokenT = Aws::String>
  void SetClientToken(ClientTokenT&& value) {
    m_clientTokenHasBeenSet = true;
    m_clientToken = std::forward<ClientTokenT>(value);
  }
  template <typename ClientTokenT = Aws::String>
  CreateMaintenanceWindowRequest& WithClientToken(ClientTokenT&& value) {
    SetClientToken(std::forward<ClientTokenT>(value));
    return *this;
  }
  ///@}

  ///@{
  /**
   * <p>Optional metadata that you assign to a resource. Tags enable you to
   * categorize a resource in different ways, such as by purpose, owner, or
   * environment. For example, you might want to tag a maintenance window to identify
   * the type of tasks it will run, the types of targets, and the environment it will
   * run in. In this case, you could specify the following key-value pairs:</p> <ul>
   * <li> <p> <code>Key=TaskType,Value=AgentUpdate</code> </p> </li> <li> <p>
   * <code>Key=OS,Value=Windows</code> </p> </li> <li> <p>
   * <code>Key=Environment,Value=Production</code> </p> </li> </ul>  <p>To add
   * tags to an existing maintenance window, use the <a>AddTagsToResource</a>
   * operation.</p>
   */
  inline const Aws::Vector<Tag>& GetTags() const { return m_tags; }
  inline bool TagsHasBeenSet() const { return m_tagsHasBeenSet; }
  template <typename TagsT = Aws::Vector<Tag>>
  void SetTags(TagsT&& value) {
    m_tagsHasBeenSet = true;
    m_tags = std::forward<TagsT>(value);
  }
  template <typename TagsT = Aws::Vector<Tag>>
  CreateMaintenanceWindowRequest& WithTags(TagsT&& value) {
    SetTags(std::forward<TagsT>(value));
    return *this;
  }
  template <typename TagsT = Tag>
  CreateMaintenanceWindowRequest& AddTags(TagsT&& value) {
    m_tagsHasBeenSet = true;
    m_tags.emplace_back(std::forward<TagsT>(value));
    return *this;
  }
  ///@}
 private:
  Aws::String m_name;

  Aws::String m_description;

  Aws::String m_startDate;

  Aws::String m_endDate;

  Aws::String m_schedule;

  Aws::String m_scheduleTimezone;

  int m_scheduleOffset{0};

  int m_duration{0};

  int m_cutoff{0};

  bool m_allowUnassociatedTargets{false};

  Aws::String m_clientToken{Aws::Utils::UUID::PseudoRandomUUID()};

  Aws::Vector<Tag> m_tags;
  bool m_nameHasBeenSet = false;
  bool m_descriptionHasBeenSet = false;
  bool m_startDateHasBeenSet = false;
  bool m_endDateHasBeenSet = false;
  bool m_scheduleHasBeenSet = false;
  bool m_scheduleTimezoneHasBeenSet = false;
  bool m_scheduleOffsetHasBeenSet = false;
  bool m_durationHasBeenSet = false;
  bool m_cutoffHasBeenSet = false;
  bool m_allowUnassociatedTargetsHasBeenSet = false;
  bool m_clientTokenHasBeenSet = true;
  bool m_tagsHasBeenSet = false;
};

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