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

#pragma once
#include <aws/autoscaling-plans/AutoScalingPlans_EXPORTS.h>
#include <aws/autoscaling-plans/model/PredefinedScalingMetricSpecification.h>
#include <aws/autoscaling-plans/model/CustomizedScalingMetricSpecification.h>
#include <utility>

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

  /**
   * <p>Describes a target tracking configuration to use with AWS Auto Scaling. Used
   * with <a>ScalingInstruction</a> and <a>ScalingPolicy</a>.</p><p><h3>See
   * Also:</h3>   <a
   * href="http://docs.aws.amazon.com/goto/WebAPI/autoscaling-plans-2018-01-06/TargetTrackingConfiguration">AWS
   * API Reference</a></p>
   */
  class TargetTrackingConfiguration
  {
  public:
    AWS_AUTOSCALINGPLANS_API TargetTrackingConfiguration() = default;
    AWS_AUTOSCALINGPLANS_API TargetTrackingConfiguration(Aws::Utils::Json::JsonView jsonValue);
    AWS_AUTOSCALINGPLANS_API TargetTrackingConfiguration& operator=(Aws::Utils::Json::JsonView jsonValue);
    AWS_AUTOSCALINGPLANS_API Aws::Utils::Json::JsonValue Jsonize() const;


    ///@{
    /**
     * <p>A predefined metric. You can specify either a predefined metric or a
     * customized metric.</p>
     */
    inline const PredefinedScalingMetricSpecification& GetPredefinedScalingMetricSpecification() const { return m_predefinedScalingMetricSpecification; }
    inline bool PredefinedScalingMetricSpecificationHasBeenSet() const { return m_predefinedScalingMetricSpecificationHasBeenSet; }
    template<typename PredefinedScalingMetricSpecificationT = PredefinedScalingMetricSpecification>
    void SetPredefinedScalingMetricSpecification(PredefinedScalingMetricSpecificationT&& value) { m_predefinedScalingMetricSpecificationHasBeenSet = true; m_predefinedScalingMetricSpecification = std::forward<PredefinedScalingMetricSpecificationT>(value); }
    template<typename PredefinedScalingMetricSpecificationT = PredefinedScalingMetricSpecification>
    TargetTrackingConfiguration& WithPredefinedScalingMetricSpecification(PredefinedScalingMetricSpecificationT&& value) { SetPredefinedScalingMetricSpecification(std::forward<PredefinedScalingMetricSpecificationT>(value)); return *this;}
    ///@}

    ///@{
    /**
     * <p>A customized metric. You can specify either a predefined metric or a
     * customized metric. </p>
     */
    inline const CustomizedScalingMetricSpecification& GetCustomizedScalingMetricSpecification() const { return m_customizedScalingMetricSpecification; }
    inline bool CustomizedScalingMetricSpecificationHasBeenSet() const { return m_customizedScalingMetricSpecificationHasBeenSet; }
    template<typename CustomizedScalingMetricSpecificationT = CustomizedScalingMetricSpecification>
    void SetCustomizedScalingMetricSpecification(CustomizedScalingMetricSpecificationT&& value) { m_customizedScalingMetricSpecificationHasBeenSet = true; m_customizedScalingMetricSpecification = std::forward<CustomizedScalingMetricSpecificationT>(value); }
    template<typename CustomizedScalingMetricSpecificationT = CustomizedScalingMetricSpecification>
    TargetTrackingConfiguration& WithCustomizedScalingMetricSpecification(CustomizedScalingMetricSpecificationT&& value) { SetCustomizedScalingMetricSpecification(std::forward<CustomizedScalingMetricSpecificationT>(value)); return *this;}
    ///@}

    ///@{
    /**
     * <p>The target value for the metric. Although this property accepts numbers of
     * type Double, it won't accept values that are either too small or too large.
     * Values must be in the range of -2^360 to 2^360.</p>
     */
    inline double GetTargetValue() const { return m_targetValue; }
    inline bool TargetValueHasBeenSet() const { return m_targetValueHasBeenSet; }
    inline void SetTargetValue(double value) { m_targetValueHasBeenSet = true; m_targetValue = value; }
    inline TargetTrackingConfiguration& WithTargetValue(double value) { SetTargetValue(value); return *this;}
    ///@}

    ///@{
    /**
     * <p>Indicates whether scale in by the target tracking scaling policy is disabled.
     * If the value is <code>true</code>, scale in is disabled and the target tracking
     * scaling policy doesn't remove capacity from the scalable resource. Otherwise,
     * scale in is enabled and the target tracking scaling policy can remove capacity
     * from the scalable resource. </p> <p>The default value is <code>false</code>.</p>
     */
    inline bool GetDisableScaleIn() const { return m_disableScaleIn; }
    inline bool DisableScaleInHasBeenSet() const { return m_disableScaleInHasBeenSet; }
    inline void SetDisableScaleIn(bool value) { m_disableScaleInHasBeenSet = true; m_disableScaleIn = value; }
    inline TargetTrackingConfiguration& WithDisableScaleIn(bool value) { SetDisableScaleIn(value); return *this;}
    ///@}

    ///@{
    /**
     * <p>The amount of time, in seconds, to wait for a previous scale-out activity to
     * take effect. This property is not used if the scalable resource is an Auto
     * Scaling group.</p> <p>With the <i>scale-out cooldown period</i>, the intention
     * is to continuously (but not excessively) scale out. After Auto Scaling
     * successfully scales out using a target tracking scaling policy, it starts to
     * calculate the cooldown time. The scaling policy won't increase the desired
     * capacity again unless either a larger scale out is triggered or the cooldown
     * period ends.</p>
     */
    inline int GetScaleOutCooldown() const { return m_scaleOutCooldown; }
    inline bool ScaleOutCooldownHasBeenSet() const { return m_scaleOutCooldownHasBeenSet; }
    inline void SetScaleOutCooldown(int value) { m_scaleOutCooldownHasBeenSet = true; m_scaleOutCooldown = value; }
    inline TargetTrackingConfiguration& WithScaleOutCooldown(int value) { SetScaleOutCooldown(value); return *this;}
    ///@}

    ///@{
    /**
     * <p>The amount of time, in seconds, after a scale-in activity completes before
     * another scale-in activity can start. This property is not used if the scalable
     * resource is an Auto Scaling group.</p> <p>With the <i>scale-in cooldown
     * period</i>, the intention is to scale in conservatively to protect your
     * application’s availability, so scale-in activities are blocked until the
     * cooldown period has expired. However, if another alarm triggers a scale-out
     * activity during the scale-in cooldown period, Auto Scaling scales out the target
     * immediately. In this case, the scale-in cooldown period stops and doesn't
     * complete.</p>
     */
    inline int GetScaleInCooldown() const { return m_scaleInCooldown; }
    inline bool ScaleInCooldownHasBeenSet() const { return m_scaleInCooldownHasBeenSet; }
    inline void SetScaleInCooldown(int value) { m_scaleInCooldownHasBeenSet = true; m_scaleInCooldown = value; }
    inline TargetTrackingConfiguration& WithScaleInCooldown(int value) { SetScaleInCooldown(value); return *this;}
    ///@}

    ///@{
    /**
     * <p>The estimated time, in seconds, until a newly launched instance can
     * contribute to the CloudWatch metrics. This value is used only if the resource is
     * an Auto Scaling group.</p>
     */
    inline int GetEstimatedInstanceWarmup() const { return m_estimatedInstanceWarmup; }
    inline bool EstimatedInstanceWarmupHasBeenSet() const { return m_estimatedInstanceWarmupHasBeenSet; }
    inline void SetEstimatedInstanceWarmup(int value) { m_estimatedInstanceWarmupHasBeenSet = true; m_estimatedInstanceWarmup = value; }
    inline TargetTrackingConfiguration& WithEstimatedInstanceWarmup(int value) { SetEstimatedInstanceWarmup(value); return *this;}
    ///@}
  private:

    PredefinedScalingMetricSpecification m_predefinedScalingMetricSpecification;
    bool m_predefinedScalingMetricSpecificationHasBeenSet = false;

    CustomizedScalingMetricSpecification m_customizedScalingMetricSpecification;
    bool m_customizedScalingMetricSpecificationHasBeenSet = false;

    double m_targetValue{0.0};
    bool m_targetValueHasBeenSet = false;

    bool m_disableScaleIn{false};
    bool m_disableScaleInHasBeenSet = false;

    int m_scaleOutCooldown{0};
    bool m_scaleOutCooldownHasBeenSet = false;

    int m_scaleInCooldown{0};
    bool m_scaleInCooldownHasBeenSet = false;

    int m_estimatedInstanceWarmup{0};
    bool m_estimatedInstanceWarmupHasBeenSet = false;
  };

} // namespace Model
} // namespace AutoScalingPlans
} // namespace Aws
