/*
Copyright AppsCode Inc. and Contributors

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.
*/

// nolint:unparam
package conversion

import (
	"unsafe"

	v1 "kmodules.xyz/offshoot-api/api/v1"
	v2 "kmodules.xyz/offshoot-api/api/v2"

	core "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/conversion"
	"k8s.io/apimachinery/pkg/runtime"
)

// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(s *runtime.Scheme) error {
	if err := s.AddGeneratedConversionFunc((*v1.ObjectMeta)(nil), (*metav1.ObjectMeta)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_ObjectMeta_To_metav1_ObjectMeta(a.(*v1.ObjectMeta), b.(*metav1.ObjectMeta), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*metav1.ObjectMeta)(nil), (*v1.ObjectMeta)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_metav1_ObjectMeta_To_v1_ObjectMeta(a.(*metav1.ObjectMeta), b.(*v1.ObjectMeta), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*v1.PodSpec)(nil), (*v2.PodSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_PodSpec_To_v2_PodSpec(a.(*v1.PodSpec), b.(*v2.PodSpec), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*v2.PodSpec)(nil), (*v1.PodSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v2_PodSpec_To_v1_PodSpec(a.(*v2.PodSpec), b.(*v1.PodSpec), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*v1.PodTemplateSpec)(nil), (*v2.PodTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v1_PodTemplateSpec_To_v2_PodTemplateSpec(a.(*v1.PodTemplateSpec), b.(*v2.PodTemplateSpec), scope)
	}); err != nil {
		return err
	}
	if err := s.AddGeneratedConversionFunc((*v2.PodTemplateSpec)(nil), (*v1.PodTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
		return Convert_v2_PodTemplateSpec_To_v1_PodTemplateSpec(a.(*v2.PodTemplateSpec), b.(*v1.PodTemplateSpec), scope)
	}); err != nil {
		return err
	}
	return nil
}

func autoConvert_v1_ObjectMeta_To_metav1_ObjectMeta(in *v1.ObjectMeta, out *metav1.ObjectMeta, s conversion.Scope) error {
	out.Labels = *(*map[string]string)(unsafe.Pointer(&in.Labels))
	out.Annotations = *(*map[string]string)(unsafe.Pointer(&in.Annotations))
	return nil
}

// Convert_v1_ObjectMeta_To_v1_ObjectMeta is an autogenerated conversion function.
func Convert_v1_ObjectMeta_To_metav1_ObjectMeta(in *v1.ObjectMeta, out *metav1.ObjectMeta, s conversion.Scope) error {
	return autoConvert_v1_ObjectMeta_To_metav1_ObjectMeta(in, out, s)
}

func autoConvert_metav1_ObjectMeta_To_v1_ObjectMeta(in *metav1.ObjectMeta, out *v1.ObjectMeta, s conversion.Scope) error {
	// WARNING: in.Name requires manual conversion: does not exist in peer-type
	// WARNING: in.GenerateName requires manual conversion: does not exist in peer-type
	// WARNING: in.Namespace requires manual conversion: does not exist in peer-type
	// WARNING: in.SelfLink requires manual conversion: does not exist in peer-type
	// WARNING: in.UID requires manual conversion: does not exist in peer-type
	// WARNING: in.ResourceVersion requires manual conversion: does not exist in peer-type
	// WARNING: in.Generation requires manual conversion: does not exist in peer-type
	// WARNING: in.CreationTimestamp requires manual conversion: does not exist in peer-type
	// WARNING: in.DeletionTimestamp requires manual conversion: does not exist in peer-type
	// WARNING: in.DeletionGracePeriodSeconds requires manual conversion: does not exist in peer-type
	out.Labels = *(*map[string]string)(unsafe.Pointer(&in.Labels))
	out.Annotations = *(*map[string]string)(unsafe.Pointer(&in.Annotations))
	// WARNING: in.OwnerReferences requires manual conversion: does not exist in peer-type
	// WARNING: in.Finalizers requires manual conversion: does not exist in peer-type
	// WARNING: in.ManagedFields requires manual conversion: does not exist in peer-type
	return nil
}

func Convert_metav1_ObjectMeta_To_v1_ObjectMeta(in *metav1.ObjectMeta, out *v1.ObjectMeta, s conversion.Scope) error {
	return autoConvert_metav1_ObjectMeta_To_v1_ObjectMeta(in, out, s)
}

func Convert_v1_PodSpec_To_v2_PodSpec(in *v1.PodSpec, out *v2.PodSpec, s conversion.Scope) error {
	if in.Volumes != nil {
		out.Volumes = in.Volumes
	} else {
		out.Volumes = nil
	}
	out.InitContainers = *(*[]core.Container)(unsafe.Pointer(&in.InitContainers))
	out.TerminationGracePeriodSeconds = (*int64)(unsafe.Pointer(in.TerminationGracePeriodSeconds))
	out.DNSPolicy = core.DNSPolicy(in.DNSPolicy)
	out.NodeSelector = *(*map[string]string)(unsafe.Pointer(&in.NodeSelector))
	out.ServiceAccountName = in.ServiceAccountName
	out.HostNetwork = in.HostNetwork
	out.HostPID = in.HostPID
	out.HostIPC = in.HostIPC
	out.ShareProcessNamespace = (*bool)(unsafe.Pointer(in.ShareProcessNamespace))
	out.SecurityContext = (*core.PodSecurityContext)(unsafe.Pointer(in.SecurityContext))
	out.ImagePullSecrets = *(*[]core.LocalObjectReference)(unsafe.Pointer(&in.ImagePullSecrets))
	// WARNING: in.Affinity requires manual conversion: does not exist in peer-type
	out.PodPlacementPolicy = in.PodPlacementPolicy
	out.SchedulerName = in.SchedulerName
	out.Tolerations = *(*[]core.Toleration)(unsafe.Pointer(&in.Tolerations))
	out.PriorityClassName = in.PriorityClassName
	out.Priority = (*int32)(unsafe.Pointer(in.Priority))
	out.DNSConfig = (*core.PodDNSConfig)(unsafe.Pointer(in.DNSConfig))
	out.RuntimeClassName = (*string)(unsafe.Pointer(in.RuntimeClassName))
	out.EnableServiceLinks = (*bool)(unsafe.Pointer(in.EnableServiceLinks))
	// WARNING: in.TopologySpreadConstraints requires manual conversion: does not exist in peer-type
	// manual
	out.Containers = []core.Container{
		{
			Args:            *(*[]string)(unsafe.Pointer(&in.Args)),
			Env:             *(*[]core.EnvVar)(unsafe.Pointer(&in.Env)),
			Resources:       in.Resources,
			LivenessProbe:   (*core.Probe)(unsafe.Pointer(in.LivenessProbe)),
			ReadinessProbe:  (*core.Probe)(unsafe.Pointer(in.ReadinessProbe)),
			Lifecycle:       (*core.Lifecycle)(unsafe.Pointer(in.Lifecycle)),
			SecurityContext: (*core.SecurityContext)(unsafe.Pointer(in.ContainerSecurityContext)),
			VolumeMounts:    *(*[]core.VolumeMount)(unsafe.Pointer(&in.VolumeMounts)),
		},
	}
	return nil
}

func Convert_v2_PodSpec_To_v1_PodSpec(in *v2.PodSpec, out *v1.PodSpec, s conversion.Scope) error {
	if in.Volumes != nil {
		out.Volumes = in.Volumes
	} else {
		out.Volumes = nil
	}
	out.InitContainers = *(*[]core.Container)(unsafe.Pointer(&in.InitContainers))
	// WARNING: in.Containers requires manual conversion: does not exist in peer-type
	// WARNING: in.EphemeralContainers requires manual conversion: does not exist in peer-type
	// WARNING: in.RestartPolicy requires manual conversion: does not exist in peer-type
	out.TerminationGracePeriodSeconds = (*int64)(unsafe.Pointer(in.TerminationGracePeriodSeconds))
	// WARNING: in.ActiveDeadlineSeconds requires manual conversion: does not exist in peer-type
	out.DNSPolicy = core.DNSPolicy(in.DNSPolicy)
	out.NodeSelector = *(*map[string]string)(unsafe.Pointer(&in.NodeSelector))
	out.ServiceAccountName = in.ServiceAccountName
	// WARNING: in.AutomountServiceAccountToken requires manual conversion: does not exist in peer-type
	// WARNING: in.NodeName requires manual conversion: does not exist in peer-type
	out.HostNetwork = in.HostNetwork
	out.HostPID = in.HostPID
	out.HostIPC = in.HostIPC
	out.ShareProcessNamespace = (*bool)(unsafe.Pointer(in.ShareProcessNamespace))
	out.SecurityContext = (*core.PodSecurityContext)(unsafe.Pointer(in.SecurityContext))
	out.ImagePullSecrets = *(*[]core.LocalObjectReference)(unsafe.Pointer(&in.ImagePullSecrets))
	out.PodPlacementPolicy = in.PodPlacementPolicy
	out.SchedulerName = in.SchedulerName
	out.Tolerations = *(*[]core.Toleration)(unsafe.Pointer(&in.Tolerations))
	// WARNING: in.HostAliases requires manual conversion: does not exist in peer-type
	out.PriorityClassName = in.PriorityClassName
	out.Priority = (*int32)(unsafe.Pointer(in.Priority))
	out.DNSConfig = (*core.PodDNSConfig)(unsafe.Pointer(in.DNSConfig))
	// WARNING: in.ReadinessGates requires manual conversion: does not exist in peer-type
	out.RuntimeClassName = (*string)(unsafe.Pointer(in.RuntimeClassName))
	out.EnableServiceLinks = (*bool)(unsafe.Pointer(in.EnableServiceLinks))
	// WARNING: in.PreemptionPolicy requires manual conversion: does not exist in peer-type
	// WARNING: in.Overhead requires manual conversion: does not exist in peer-type
	// WARNING: in.SetHostnameAsFQDN requires manual conversion: does not exist in peer-type
	// WARNING: in.OS requires manual conversion: does not exist in peer-type
	// WARNING: in.HostUsers requires manual conversion: does not exist in peer-type
	if len(in.Containers) > 0 {
		c := in.Containers[0]
		out.Args = *(*[]string)(unsafe.Pointer(&c.Args))
		out.Env = *(*[]core.EnvVar)(unsafe.Pointer(&c.Env))
		out.Resources = c.Resources
		out.LivenessProbe = (*core.Probe)(unsafe.Pointer(c.LivenessProbe))
		out.ReadinessProbe = (*core.Probe)(unsafe.Pointer(c.ReadinessProbe))
		out.Lifecycle = (*core.Lifecycle)(unsafe.Pointer(c.Lifecycle))
		out.ContainerSecurityContext = (*core.SecurityContext)(unsafe.Pointer(c.SecurityContext))
		out.VolumeMounts = *(*[]core.VolumeMount)(unsafe.Pointer(&c.VolumeMounts))
	}
	return nil
}

func autoConvert_v1_PodTemplateSpec_To_v2_PodTemplateSpec(in *v1.PodTemplateSpec, out *v2.PodTemplateSpec, s conversion.Scope) error {
	out.ObjectMeta = in.ObjectMeta
	out.Controller = in.Controller
	if err := Convert_v1_PodSpec_To_v2_PodSpec(&in.Spec, &out.Spec, s); err != nil {
		return err
	}
	return nil
}

// Convert_v1_PodTemplateSpec_To_v2_PodTemplateSpec is an autogenerated conversion function.
func Convert_v1_PodTemplateSpec_To_v2_PodTemplateSpec(in *v1.PodTemplateSpec, out *v2.PodTemplateSpec, s conversion.Scope) error {
	return autoConvert_v1_PodTemplateSpec_To_v2_PodTemplateSpec(in, out, s)
}

func autoConvert_v2_PodTemplateSpec_To_v1_PodTemplateSpec(in *v2.PodTemplateSpec, out *v1.PodTemplateSpec, s conversion.Scope) error {
	out.ObjectMeta = in.ObjectMeta
	out.Controller = in.Controller
	if err := Convert_v2_PodSpec_To_v1_PodSpec(&in.Spec, &out.Spec, s); err != nil {
		return err
	}
	return nil
}

// Convert_v2_PodTemplateSpec_To_v1_PodTemplateSpec is an autogenerated conversion function.
func Convert_v2_PodTemplateSpec_To_v1_PodTemplateSpec(in *v2.PodTemplateSpec, out *v1.PodTemplateSpec, s conversion.Scope) error {
	return autoConvert_v2_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s)
}
