/*
Copyright 2020 The Kubernetes Authors.

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 v1alpha3

import (
	apimachineryconversion "k8s.io/apimachinery/pkg/conversion"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
	"sigs.k8s.io/controller-runtime/pkg/conversion"

	expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
	utilconversion "sigs.k8s.io/cluster-api/util/conversion"
)

// Convert_v1alpha3_MachinePoolSpec_To_v1beta1_MachinePoolSpec is an autogenerated conversion function.
func Convert_v1alpha3_MachinePoolSpec_To_v1beta1_MachinePoolSpec(in *MachinePoolSpec, out *expv1.MachinePoolSpec, s apimachineryconversion.Scope) error {
	return autoConvert_v1alpha3_MachinePoolSpec_To_v1beta1_MachinePoolSpec(in, out, s)
}

func Convert_v1alpha3_MachinePool_To_v1beta1_MachinePool(in *MachinePool, out *expv1.MachinePool, s apimachineryconversion.Scope) error {
	if err := autoConvert_v1alpha3_MachinePool_To_v1beta1_MachinePool(in, out, s); err != nil {
		return err
	}

	// Replace v1alpha3 finalizer to allow old MachinePools to get deleted.
	if controllerutil.ContainsFinalizer(out, MachinePoolFinalizer) {
		controllerutil.RemoveFinalizer(out, MachinePoolFinalizer)
		controllerutil.AddFinalizer(out, expv1.MachinePoolFinalizer)
	}

	return nil
}

func Convert_v1beta1_MachinePool_To_v1alpha3_MachinePool(in *expv1.MachinePool, out *MachinePool, s apimachineryconversion.Scope) error {
	if err := autoConvert_v1beta1_MachinePool_To_v1alpha3_MachinePool(in, out, s); err != nil {
		return err
	}

	// Replace v1beta1 finalizer to allow old MachinePools to get deleted.
	if controllerutil.ContainsFinalizer(out, expv1.MachinePoolFinalizer) {
		controllerutil.RemoveFinalizer(out, expv1.MachinePoolFinalizer)
		controllerutil.AddFinalizer(out, MachinePoolFinalizer)
	}

	return nil
}

func (src *MachinePool) ConvertTo(dstRaw conversion.Hub) error {
	dst := dstRaw.(*expv1.MachinePool)

	if err := Convert_v1alpha3_MachinePool_To_v1beta1_MachinePool(src, dst, nil); err != nil {
		return err
	}

	// Manually restore data.
	restored := &expv1.MachinePool{}
	if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok {
		return err
	}
	dst.Spec.Template.Spec.NodeDeletionTimeout = restored.Spec.Template.Spec.NodeDeletionTimeout
	dst.Spec.Template.Spec.NodeVolumeDetachTimeout = restored.Spec.Template.Spec.NodeVolumeDetachTimeout
	return nil
}

func (dst *MachinePool) ConvertFrom(srcRaw conversion.Hub) error {
	src := srcRaw.(*expv1.MachinePool)

	if err := Convert_v1beta1_MachinePool_To_v1alpha3_MachinePool(src, dst, nil); err != nil {
		return err
	}

	return utilconversion.MarshalData(src, dst)
}

func (src *MachinePoolList) ConvertTo(dstRaw conversion.Hub) error {
	dst := dstRaw.(*expv1.MachinePoolList)

	return Convert_v1alpha3_MachinePoolList_To_v1beta1_MachinePoolList(src, dst, nil)
}

func (dst *MachinePoolList) ConvertFrom(srcRaw conversion.Hub) error {
	src := srcRaw.(*expv1.MachinePoolList)

	return Convert_v1beta1_MachinePoolList_To_v1alpha3_MachinePoolList(src, dst, nil)
}
