// File generated by the kubebuilder framework:
// https://github.com/kubernetes-sigs/kubebuilder

/*
Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/intstr"
)

// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required.  Any new fields you add must have json tags for the fields to be serialized.

// ZoneAwareUpdateSpec defines the desired state of ZoneAwareUpdate
type ZoneAwareUpdateSpec struct {
	// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
	// Important: Run "make" to regenerate code after modifying this file

	// The name of the StatefulSet for which the ZoneAwareUpdate applies to.
	StatefulSet string `json:"statefulset,omitempty"`

	// Max number (or %) of pods that can be updated at the same time.
	MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`

	// The exponential growth rate in float string. Default value is 2.0.
	// It's possible to disable exponential updates by setting the ExponentialFactor to 0. In this case,
	// the number of pods updated at each step is defined only by the MaxUnavailable param.
	//+kubebuilder:default:="2.0"
	ExponentialFactor string `json:"exponentialFactor,omitempty"`

	// CW alarm name used to pause/skip updates.
	// Alarm should be on the same account and region.
	// +optional
	PauseRolloutAlarm string `json:"pauseRolloutAlarm,omitempty"`

	// Flag to ignore the PauseRolloutAlarm (default false)
	// +optional
	IgnoreAlarm bool `json:"ignoreAlarm,omitempty"`

	// Dryn-run mode that can be used to test the new controller before enable it
	// +optional
	DryRun bool `json:"dryRun,omitempty"`
}

// ZoneAwareUpdateStatus defines the observed state of ZoneAwareUpdate
type ZoneAwareUpdateStatus struct {
	// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
	// Important: Run "make" to regenerate code after modifying this file

	// CurrentRevision indicates the version of the StatefulSet used to generate Pods
	// +optional
	CurrentRevision string `json:"currentRevision,omitempty"`

	// UpdateRevision indicates the new version of the StatefulSet
	// +optional
	UpdateRevision string `json:"updateRevision,omitempty"`

	// OldReplicas is the number of Pods *per zone* in the CurrentRevision, when there is new UpdateRevision.
	// It becomes zero for all zones when all pods are in the new revision.
	// +optional
	OldReplicas map[string]int32 `json:"oldReplicas,omitempty"`

	// UpdateStep is used to track the rollout progress. Everytime pods are deleted/updated this is increased.
	// It becomes zero when all pods are in the new revision.
	// +optional
	UpdateStep int32 `json:"updateStep,omitempty"`

	// DeletedReplicas is the number of replicas deleted in the last reconcile loop.
	// +optional
	DeletedReplicas int32 `json:"deletedReplicas,omitempty"`

	// PausedRollout indicates if the rollout was paused becaused the PauseRolloutAlarm is in alarm.
	// +optional
	PausedRollout bool `json:"pausedRollout,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName=zau

// ZoneAwareUpdate is the Schema for the zoneawareupdates API
type ZoneAwareUpdate struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   ZoneAwareUpdateSpec   `json:"spec,omitempty"`
	Status ZoneAwareUpdateStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// ZoneAwareUpdateList contains a list of ZoneAwareUpdate
type ZoneAwareUpdateList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ZoneAwareUpdate `json:"items"`
}

func init() {
	SchemeBuilder.Register(&ZoneAwareUpdate{}, &ZoneAwareUpdateList{})
}
