// Code generated by lingon. EDIT AS MUCH AS YOU LIKE.

package tekton

import (
	"context"
	"errors"
	"os"
	"os/exec"

	"github.com/golingon/lingon/pkg/kube"
	admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
	appsv1 "k8s.io/api/apps/v1"
	autoscalingv2 "k8s.io/api/autoscaling/v2"
	corev1 "k8s.io/api/core/v1"
	rbacv1 "k8s.io/api/rbac/v1"
	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
)

// validate the struct implements the interface
var _ kube.Exporter = (*Tekton)(nil)

// Tekton contains kubernetes manifests
type Tekton struct {
	kube.App

	AggregateEditCR                                             *rbacv1.ClusterRole
	AggregateViewCR                                             *rbacv1.ClusterRole
	BundleresolverConfigCM                                      *corev1.ConfigMap
	ClusterResolverConfigCM                                     *corev1.ConfigMap
	ClustertasksDevCRD                                          *apiextensionsv1.CustomResourceDefinition
	ConfigArtifactBucketCM                                      *corev1.ConfigMap
	ConfigArtifactPvcCM                                         *corev1.ConfigMap
	ConfigDefaultsCM                                            *corev1.ConfigMap
	ConfigLeaderElectionCM                                      *corev1.ConfigMap
	ConfigLeaderElectionCM1                                     *corev1.ConfigMap
	ConfigLoggingCM                                             *corev1.ConfigMap
	ConfigLoggingCM2                                            *corev1.ConfigMap
	ConfigObservabilityCM                                       *corev1.ConfigMap
	ConfigObservabilityCM3                                      *corev1.ConfigMap
	ConfigRegistryCertCM                                        *corev1.ConfigMap
	ConfigSpireCM                                               *corev1.ConfigMap
	ConfigTrustedResourcesCM                                    *corev1.ConfigMap
	ConfigWebhookPipelineDevValidatingwebhookconfigurations     *admissionregistrationv1.ValidatingWebhookConfiguration
	CustomrunsDevCRD                                            *apiextensionsv1.CustomResourceDefinition
	FeatureFlagsCM                                              *corev1.ConfigMap
	GitResolverConfigCM                                         *corev1.ConfigMap
	HubresolverConfigCM                                         *corev1.ConfigMap
	PipelineresourcesDevCRD                                     *apiextensionsv1.CustomResourceDefinition
	PipelinerunsDevCRD                                          *apiextensionsv1.CustomResourceDefinition
	PipelinesControllerClusterAccessCR                          *rbacv1.ClusterRole
	PipelinesControllerClusterAccessCRB                         *rbacv1.ClusterRoleBinding
	PipelinesControllerDeploy                                   *appsv1.Deployment
	PipelinesControllerLeaderelectionRB                         *rbacv1.RoleBinding
	PipelinesControllerRB                                       *rbacv1.RoleBinding
	PipelinesControllerRole                                     *rbacv1.Role
	PipelinesControllerSA                                       *corev1.ServiceAccount
	PipelinesControllerSVC                                      *corev1.Service
	PipelinesControllerTenantAccessCR                           *rbacv1.ClusterRole
	PipelinesControllerTenantAccessCRB                          *rbacv1.ClusterRoleBinding
	PipelinesDevCRD                                             *apiextensionsv1.CustomResourceDefinition
	PipelinesInfoCM                                             *corev1.ConfigMap
	PipelinesInfoRB                                             *rbacv1.RoleBinding
	PipelinesInfoRole                                           *rbacv1.Role
	PipelinesLeaderElectionRole                                 *rbacv1.Role
	PipelinesNS                                                 *corev1.Namespace
	PipelinesRemoteResolversDeploy                              *appsv1.Deployment
	PipelinesResolversCRB                                       *rbacv1.ClusterRoleBinding
	PipelinesResolversNS                                        *corev1.Namespace
	PipelinesResolversNamespaceRbacRB                           *rbacv1.RoleBinding
	PipelinesResolversNamespaceRbacRole                         *rbacv1.Role
	PipelinesResolversResolutionRequestUpdatesCR                *rbacv1.ClusterRole
	PipelinesResolversSA                                        *corev1.ServiceAccount
	PipelinesWebhookClusterAccessCR                             *rbacv1.ClusterRole
	PipelinesWebhookClusterAccessCRB                            *rbacv1.ClusterRoleBinding
	PipelinesWebhookDeploy                                      *appsv1.Deployment
	PipelinesWebhookHPA                                         *autoscalingv2.HorizontalPodAutoscaler
	PipelinesWebhookLeaderelectionRB                            *rbacv1.RoleBinding
	PipelinesWebhookRB                                          *rbacv1.RoleBinding
	PipelinesWebhookRole                                        *rbacv1.Role
	PipelinesWebhookSA                                          *corev1.ServiceAccount
	PipelinesWebhookSVC                                         *corev1.Service
	ResolutionrequestsResolutionDevCRD                          *apiextensionsv1.CustomResourceDefinition
	ResolversFeatureFlagsCM                                     *corev1.ConfigMap
	RunsDevCRD                                                  *apiextensionsv1.CustomResourceDefinition
	TaskrunsDevCRD                                              *apiextensionsv1.CustomResourceDefinition
	TasksDevCRD                                                 *apiextensionsv1.CustomResourceDefinition
	ValidationWebhookPipelineDevValidatingwebhookconfigurations *admissionregistrationv1.ValidatingWebhookConfiguration
	VerificationpoliciesDevCRD                                  *apiextensionsv1.CustomResourceDefinition
	WebhookCertsSecrets                                         *corev1.Secret
	WebhookPipelineDevMutatingwebhookconfigurations             *admissionregistrationv1.MutatingWebhookConfiguration
}

// New creates a new Tekton
func New() *Tekton {
	return &Tekton{
		AggregateEditCR:          AggregateEditCR,
		AggregateViewCR:          AggregateViewCR,
		BundleresolverConfigCM:   BundleresolverConfigCM,
		ClusterResolverConfigCM:  ClusterResolverConfigCM,
		ClustertasksDevCRD:       ClustertasksDevCRD,
		ConfigArtifactBucketCM:   ConfigArtifactBucketCM,
		ConfigArtifactPvcCM:      ConfigArtifactPvcCM,
		ConfigDefaultsCM:         ConfigDefaultsCM,
		ConfigLeaderElectionCM:   ConfigLeaderElectionCM,
		ConfigLeaderElectionCM1:  ConfigLeaderElectionCM1,
		ConfigLoggingCM:          ConfigLoggingCM,
		ConfigLoggingCM2:         ConfigLoggingCM2,
		ConfigObservabilityCM:    ConfigObservabilityCM,
		ConfigObservabilityCM3:   ConfigObservabilityCM3,
		ConfigRegistryCertCM:     ConfigRegistryCertCM,
		ConfigSpireCM:            ConfigSpireCM,
		ConfigTrustedResourcesCM: ConfigTrustedResourcesCM,
		ConfigWebhookPipelineDevValidatingwebhookconfigurations: ConfigWebhookPipelineDevValidatingwebhookconfigurations,
		CustomrunsDevCRD:                             CustomrunsDevCRD,
		FeatureFlagsCM:                               FeatureFlagsCM,
		GitResolverConfigCM:                          GitResolverConfigCM,
		HubresolverConfigCM:                          HubresolverConfigCM,
		PipelineresourcesDevCRD:                      PipelineresourcesDevCRD,
		PipelinerunsDevCRD:                           PipelinerunsDevCRD,
		PipelinesControllerClusterAccessCR:           PipelinesControllerClusterAccessCR,
		PipelinesControllerClusterAccessCRB:          PipelinesControllerClusterAccessCRB,
		PipelinesControllerDeploy:                    PipelinesControllerDeploy,
		PipelinesControllerLeaderelectionRB:          PipelinesControllerLeaderelectionRB,
		PipelinesControllerRB:                        PipelinesControllerRB,
		PipelinesControllerRole:                      PipelinesControllerRole,
		PipelinesControllerSA:                        PipelinesControllerSA,
		PipelinesControllerSVC:                       PipelinesControllerSVC,
		PipelinesControllerTenantAccessCR:            PipelinesControllerTenantAccessCR,
		PipelinesControllerTenantAccessCRB:           PipelinesControllerTenantAccessCRB,
		PipelinesDevCRD:                              PipelinesDevCRD,
		PipelinesInfoCM:                              PipelinesInfoCM,
		PipelinesInfoRB:                              PipelinesInfoRB,
		PipelinesInfoRole:                            PipelinesInfoRole,
		PipelinesLeaderElectionRole:                  PipelinesLeaderElectionRole,
		PipelinesNS:                                  PipelinesNS,
		PipelinesRemoteResolversDeploy:               PipelinesRemoteResolversDeploy,
		PipelinesResolversCRB:                        PipelinesResolversCRB,
		PipelinesResolversNS:                         PipelinesResolversNS,
		PipelinesResolversNamespaceRbacRB:            PipelinesResolversNamespaceRbacRB,
		PipelinesResolversNamespaceRbacRole:          PipelinesResolversNamespaceRbacRole,
		PipelinesResolversResolutionRequestUpdatesCR: PipelinesResolversResolutionRequestUpdatesCR,
		PipelinesResolversSA:                         PipelinesResolversSA,
		PipelinesWebhookClusterAccessCR:              PipelinesWebhookClusterAccessCR,
		PipelinesWebhookClusterAccessCRB:             PipelinesWebhookClusterAccessCRB,
		PipelinesWebhookDeploy:                       PipelinesWebhookDeploy,
		PipelinesWebhookHPA:                          PipelinesWebhookHPA,
		PipelinesWebhookLeaderelectionRB:             PipelinesWebhookLeaderelectionRB,
		PipelinesWebhookRB:                           PipelinesWebhookRB,
		PipelinesWebhookRole:                         PipelinesWebhookRole,
		PipelinesWebhookSA:                           PipelinesWebhookSA,
		PipelinesWebhookSVC:                          PipelinesWebhookSVC,
		ResolutionrequestsResolutionDevCRD:           ResolutionrequestsResolutionDevCRD,
		ResolversFeatureFlagsCM:                      ResolversFeatureFlagsCM,
		RunsDevCRD:                                   RunsDevCRD,
		TaskrunsDevCRD:                               TaskrunsDevCRD,
		TasksDevCRD:                                  TasksDevCRD,
		ValidationWebhookPipelineDevValidatingwebhookconfigurations: ValidationWebhookPipelineDevValidatingwebhookconfigurations,
		VerificationpoliciesDevCRD:                                  VerificationpoliciesDevCRD,
		WebhookCertsSecrets:                                         WebhookCertsSecrets,
		WebhookPipelineDevMutatingwebhookconfigurations:             WebhookPipelineDevMutatingwebhookconfigurations,
	}
}

// Apply applies the kubernetes objects to the cluster
func (a *Tekton) Apply(ctx context.Context) error {
	return Apply(ctx, a)
}

// Export exports the kubernetes objects to YAML files in the given directory
func (a *Tekton) Export(dir string) error {
	return kube.Export(a, kube.WithExportOutputDirectory(dir))
}

// Apply applies the kubernetes objects contained in Exporter to the cluster
func Apply(ctx context.Context, km kube.Exporter) error {
	cmd := exec.CommandContext(ctx, "kubectl", "apply", "-f", "-")
	cmd.Env = os.Environ()        // inherit environment in case we need to use kubectl from a container
	stdin, err := cmd.StdinPipe() // pipe to pass data to kubectl
	if err != nil {
		return err
	}

	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	go func() {
		defer func() {
			err = errors.Join(err, stdin.Close())
		}()
		if errEW := kube.Export(
			km,
			kube.WithExportWriter(stdin),
		); errEW != nil {
			err = errors.Join(err, errEW)
		}
	}()

	if errS := cmd.Start(); errS != nil {
		return errors.Join(err, errS)
	}

	// waits for the command to exit and waits for any copying
	// to stdin or copying from stdout or stderr to complete
	return errors.Join(err, cmd.Wait())
}

// P converts T to *T, useful for basic types
func P[T any](t T) *T {
	return &t
}
