/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 v1beta1

import (
	"fmt"
	"github.com/go-logr/logr"
	zkApi "github.com/pravega/zookeeper-operator/api/v1beta1"
	"strconv"
	"strings"

	"k8s.io/apimachinery/pkg/util/intstr"

	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
	DefaultPullPolicy = "" // This will use the default pullPolicy of Always when the tag is "latest" and IfNotPresent for all other tags.

	DefaultSolrReplicas = int32(3)
	DefaultSolrRepo     = "library/solr"
	DefaultSolrVersion  = "8.11"
	DefaultSolrJavaMem  = "-Xms1g -Xmx2g"
	DefaultSolrOpts     = ""
	DefaultSolrLogLevel = "INFO"
	DefaultSolrGCTune   = ""

	DefaultBusyBoxImageRepo    = "library/busybox"
	DefaultBusyBoxImageVersion = "1.28.0-glibc"

	DefaultZkReplicas                                = int32(3)
	DefaultZkStorage                                 = "5Gi"
	DefaultZkRepo                                    = "pravega/zookeeper"
	DefaultZkVersion                                 = ""
	DefaultZkVolumeReclaimPolicy VolumeReclaimPolicy = "Retain"

	SolrTechnologyLabel      = "solr-cloud"
	ZookeeperTechnologyLabel = "zookeeper"

	DefaultBasicAuthUsername = "k8s-oper"

	LegacyBackupRepositoryName = "legacy_volume_repository"
)

// SolrCloudSpec defines the desired state of SolrCloud
type SolrCloudSpec struct {
	// The number of solr nodes to run
	// +optional
	Replicas *int32 `json:"replicas,omitempty"`

	// The information for the Zookeeper this SolrCloud should connect to
	// Can be a zookeeper that is running, or one that is created by the solr operator
	// +optional
	ZookeeperRef *ZookeeperRef `json:"zookeeperRef,omitempty"`

	// +optional
	SolrImage *ContainerImage `json:"solrImage,omitempty"`

	// Customize how the cloud data is stored.
	// If neither "persistent" or "ephemeral" is provided, then ephemeral storage will be used by default.
	//
	// +optional
	StorageOptions SolrDataStorageOptions `json:"dataStorage,omitempty"`

	// Provide custom options for kubernetes objects created for the Solr Cloud.
	// +optional
	CustomSolrKubeOptions CustomSolrKubeOptions `json:"customSolrKubeOptions,omitempty"`

	// Customize how Solr is addressed both internally and externally in Kubernetes.
	// +optional
	SolrAddressability SolrAddressabilityOptions `json:"solrAddressability,omitempty"`

	// Define how Solr rolling updates are executed.
	// +optional
	UpdateStrategy SolrUpdateStrategy `json:"updateStrategy,omitempty"`

	// Define how Solr nodes should be available.
	// +optional
	Availability SolrAvailabilityOptions `json:"availability,omitempty"`

	// +optional
	BusyBoxImage *ContainerImage `json:"busyBoxImage,omitempty"`

	// +optional
	SolrJavaMem string `json:"solrJavaMem,omitempty"`

	// You can add common system properties to the SOLR_OPTS environment variable
	// SolrOpts is the string interface for these optional settings
	// +optional
	SolrOpts string `json:"solrOpts,omitempty"`

	// This will add java system properties for connecting to Zookeeper.
	// SolrZkOpts is the string interface for these optional settings
	// +optional
	SolrZkOpts string `json:"solrZkOpts,omitempty"`

	// Set the Solr Log level, defaults to INFO
	// +optional
	SolrLogLevel string `json:"solrLogLevel,omitempty"`

	// Set GC Tuning configuration through GC_TUNE environment variable
	// +optional
	SolrGCTune string `json:"solrGCTune,omitempty"`

	// Options to enable the server TLS certificate for Solr pods
	// +optional
	SolrTLS *SolrTLSOptions `json:"solrTLS,omitempty"`

	// Options to configure client TLS certificate for Solr pods
	// +optional
	SolrClientTLS *SolrTLSOptions `json:"solrClientTLS,omitempty"`

	// Options to enable Solr security
	// +optional
	SolrSecurity *SolrSecurityOptions `json:"solrSecurity,omitempty"`

	// Allows specification of multiple different "repositories" for Solr to use when backing up data.
	//+optional
	//+listType:=map
	//+listMapKey:=name
	BackupRepositories []SolrBackupRepository `json:"backupRepositories,omitempty"`

	// List of Solr Modules to be loaded when starting Solr
	// Note: You do not need to specify a module if it is required by another property (e.g. backupRepositories[].gcs)
	//
	//+optional
	SolrModules []string `json:"solrModules,omitempty"`

	// List of paths in the Solr Docker image to load in the classpath.
	// Note: Solr Modules will be auto-loaded if specified in the "solrModules" property. There is no need to specify them here as well.
	//
	//+optional
	AdditionalLibs []string `json:"additionalLibs,omitempty"`
}

func (spec *SolrCloudSpec) withDefaults(logger logr.Logger) (changed bool) {
	if spec.Replicas == nil {
		changed = true
		r := DefaultSolrReplicas
		spec.Replicas = &r
	}

	if spec.SolrJavaMem == "" && DefaultSolrJavaMem != "" {
		changed = true
		spec.SolrJavaMem = DefaultSolrJavaMem
	}

	if spec.SolrOpts == "" && DefaultSolrOpts != "" {
		changed = true
		spec.SolrOpts = DefaultSolrOpts
	}

	if spec.SolrLogLevel == "" && DefaultSolrLogLevel != "" {
		changed = true
		spec.SolrLogLevel = DefaultSolrLogLevel
	}

	if spec.SolrGCTune == "" && DefaultSolrGCTune != "" {
		changed = true
		spec.SolrGCTune = DefaultSolrGCTune
	}

	changed = spec.SolrAddressability.withDefaults(spec.SolrTLS != nil, logger) || changed

	changed = spec.UpdateStrategy.withDefaults() || changed

	if spec.ZookeeperRef == nil {
		spec.ZookeeperRef = &ZookeeperRef{}
	}
	changed = spec.ZookeeperRef.withDefaults() || changed

	if spec.SolrImage == nil {
		spec.SolrImage = &ContainerImage{}
	}
	changed = spec.SolrImage.withDefaults(DefaultSolrRepo, DefaultSolrVersion, DefaultPullPolicy) || changed

	changed = spec.StorageOptions.withDefaults() || changed

	if spec.BusyBoxImage == nil {
		c := ContainerImage{}
		spec.BusyBoxImage = &c
	}
	changed = spec.BusyBoxImage.withDefaults(DefaultBusyBoxImageRepo, DefaultBusyBoxImageVersion, DefaultPullPolicy) || changed

	return changed
}

type CustomSolrKubeOptions struct {
	// SolrPodOptions defines the custom options for solrCloud pods.
	// +optional
	PodOptions *PodOptions `json:"podOptions,omitempty"`

	// StatefulSetOptions defines the custom options for the solrCloud StatefulSet.
	// +optional
	StatefulSetOptions *StatefulSetOptions `json:"statefulSetOptions,omitempty"`

	// CommonServiceOptions defines the custom options for the common solrCloud Service.
	// +optional
	CommonServiceOptions *ServiceOptions `json:"commonServiceOptions,omitempty"`

	// HeadlessServiceOptions defines the custom options for the headless solrCloud Service.
	// +optional
	HeadlessServiceOptions *ServiceOptions `json:"headlessServiceOptions,omitempty"`

	// NodeServiceOptions defines the custom options for the individual solrCloud Node services, if they are created.
	// These services will only be created when exposing SolrNodes externally via an Ingress in the AddressabilityOptions.
	// +optional
	NodeServiceOptions *ServiceOptions `json:"nodeServiceOptions,omitempty"`

	// ServiceOptions defines the custom options for the solrCloud ConfigMap.
	// +optional
	ConfigMapOptions *ConfigMapOptions `json:"configMapOptions,omitempty"`

	// IngressOptions defines the custom options for the solrCloud Ingress.
	// +optional
	IngressOptions *IngressOptions `json:"ingressOptions,omitempty"`
}

type SolrDataStorageOptions struct {

	// PersistentStorage is the specification for how the persistent Solr data storage should be configured.
	//
	// This option cannot be used with the "ephemeral" option.
	//
	// +optional
	PersistentStorage *SolrPersistentDataStorageOptions `json:"persistent,omitempty"`

	// EphemeralStorage is the specification for how the ephemeral Solr data storage should be configured.
	//
	// This option cannot be used with the "persistent" option.
	// Ephemeral storage is used by default if neither "persistent" or "ephemeral" is provided.
	//
	// +optional
	EphemeralStorage *SolrEphemeralDataStorageOptions `json:"ephemeral,omitempty"`
}

func (opts *SolrDataStorageOptions) withDefaults() (changed bool) {
	if opts.PersistentStorage != nil {
		changed = changed || opts.PersistentStorage.withDefaults()
	}

	return changed
}

type SolrPersistentDataStorageOptions struct {

	// VolumeReclaimPolicy determines how the Solr Cloud's PVCs will be treated after the cloud is deleted.
	//   - Retain: This is the default Kubernetes policy, where PVCs created for StatefulSets are not deleted when the StatefulSet is deleted.
	//   - Delete: The PVCs will be deleted by the Solr Operator after the SolrCloud object is deleted.
	// The default value is Retain, so no data will be deleted unless explicitly configured.
	// +optional
	VolumeReclaimPolicy VolumeReclaimPolicy `json:"reclaimPolicy,omitempty"`

	// PersistentVolumeClaimTemplate is the PVC object for the solr node to store its data.
	// Within metadata, the Name, Labels and Annotations are able to be specified, but defaults will be provided if necessary.
	// The entire Spec is customizable, however there will be defaults provided if necessary.
	// This field is optional. If no PVC spec is provided, then a default will be provided.
	// +optional
	PersistentVolumeClaimTemplate PersistentVolumeClaimTemplate `json:"pvcTemplate,omitempty"`
}

func (opts *SolrPersistentDataStorageOptions) withDefaults() (changed bool) {
	if opts.VolumeReclaimPolicy == "" {
		changed = true
		opts.VolumeReclaimPolicy = VolumeReclaimPolicyRetain
	}

	return changed
}

// VolumeReclaimPolicy is a string enumeration type that enumerates
// all possible ways that a SolrCloud can treat it's PVCs after its death
// +kubebuilder:validation:Enum=Retain;Delete
type VolumeReclaimPolicy string

const (
	// All pod PVCs are retained after the SolrCloud is deleted.
	VolumeReclaimPolicyRetain VolumeReclaimPolicy = "Retain"

	// All pod PVCs are deleted after the SolrCloud is deleted.
	VolumeReclaimPolicyDelete VolumeReclaimPolicy = "Delete"
)

// PersistentVolumeClaimTemplate is used to produce
// PersistentVolumeClaim objects as part of an EphemeralVolumeSource.
type PersistentVolumeClaimTemplate struct {
	// May contain labels and annotations that will be copied into the PVC
	// when creating it. No other fields are allowed and will be rejected during
	// validation.
	//
	// +optional
	ObjectMeta TemplateMeta `json:"metadata,omitempty"`

	// The specification for the PersistentVolumeClaim. The entire content is
	// copied unchanged into the PVC that gets created from this
	// template. The same fields as in a PersistentVolumeClaim
	// are also valid here.
	//
	// +optional
	Spec corev1.PersistentVolumeClaimSpec `json:"spec,omitempty"`
}

// TemplateMeta is metadata for templated resources.
type TemplateMeta struct {
	// Name must be unique within a namespace. Is required when creating resources, although
	// some resources may allow a client to request the generation of an appropriate name
	// automatically. Name is primarily intended for creation idempotence and configuration
	// definition.
	// Cannot be updated.
	// More info: http://kubernetes.io/docs/user-guide/identifiers#names
	// +optional
	Name string `json:"name,omitempty"`

	// Map of string keys and values that can be used to organize and categorize
	// (scope and select) objects. May match selectors of replication controllers
	// and services.
	// More info: http://kubernetes.io/docs/user-guide/labels
	// +optional
	Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"`

	// Annotations is an unstructured key value map stored with a resource that may be
	// set by external tools to store and retrieve arbitrary metadata. They are not
	// queryable and should be preserved when modifying objects.
	// More info: http://kubernetes.io/docs/user-guide/annotations
	// +optional
	Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"`
}

type SolrEphemeralDataStorageOptions struct {
	// HostPathVolumeSource is an optional config to specify a path on the host machine to store Solr data.
	//
	// If hostPath is omitted, then the default EmptyDir is used, otherwise hostPath takes precedence over EmptyDir.
	// +optional
	HostPath *corev1.HostPathVolumeSource `json:"hostPath,omitempty"`
	//EmptyDirVolumeSource is an optional config for the emptydir volume that will store Solr data.
	// +optional
	EmptyDir *corev1.EmptyDirVolumeSource `json:"emptyDir,omitempty"`
}

// +kubebuilder:validation:MinProperties:=2
// +kubebuilder:validation:MaxProperties:=2
type SolrBackupRepository struct {
	// A name used to identify this local storage profile.  Values should follow RFC-1123.  (See here for more details:
	// https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names)
	//
	// +kubebuilder:validation:Pattern:=[a-zA-Z0-9]([-_a-zA-Z0-9]*[a-zA-Z0-9])?
	// +kubebuilder:validation:MinLength:=1
	// +kubebuilder:validation:MaxLength:=100
	Name string `json:"name"`

	// A GCSRepository for Solr to use when backing up and restoring collections.
	//+optional
	GCS *GcsRepository `json:"gcs,omitempty"`

	// An S3Repository for Solr to use when backing up and restoring collections.
	//+optional
	S3 *S3Repository `json:"s3,omitempty"`

	// Allows specification of a "repository" for Solr to use when backing up data "locally".
	//+optional
	Volume *VolumeRepository `json:"volume,omitempty"`
}

type GcsRepository struct {
	// The name of the GCS bucket that all backup data will be stored in
	Bucket string `json:"bucket"`

	// The name & key of a Kubernetes secret holding a Google cloud service account key.  Must be set unless deployed in
	// GKE and making use of Google's "Workplace Identity" feature.
	//+optional
	GcsCredentialSecret *corev1.SecretKeySelector `json:"gcsCredentialSecret,omitempty"`

	// An already-created chroot within the bucket to store data in. Defaults to the root path "/" if not specified.
	// +optional
	BaseLocation string `json:"baseLocation,omitempty"`
}

type S3Repository struct {
	// The S3 region to store the backup data in
	Region string `json:"region"`

	// The name of the S3 bucket that all backup data will be stored in
	Bucket string `json:"bucket"`

	// Options for specifying S3Credentials. This is optional in case you want to mount this information yourself.
	// However, if you do not include these credentials, and you do not load them yourself via a mount or EnvVars,
	// you will likely see errors when taking s3 backups.
	//
	// If running in EKS, you can create an IAMServiceAccount that uses a role permissioned for this S3 bucket.
	// Then use that serviceAccountName for your SolrCloud, and the credentials should be auto-populated.
	//
	// +optional
	Credentials *S3Credentials `json:"credentials,omitempty"`

	// An already-created chroot within the bucket to store data in. Defaults to the root path "/" if not specified.
	// +optional
	BaseLocation string `json:"baseLocation,omitempty"`

	// The full endpoint URL to use when connecting with S3 (or a supported S3 compatible interface)
	// +optional
	Endpoint string `json:"endpoint,omitempty"`

	// The full proxy URL to use when connecting with S3
	// +optional
	ProxyUrl string `json:"proxyUrl,omitempty"`
}

type S3Credentials struct {
	// The name & key of a Kubernetes secret holding an AWS Access Key ID
	// +optional
	AccessKeyIdSecret *corev1.SecretKeySelector `json:"accessKeyIdSecret,omitempty"`

	// The name & key of a Kubernetes secret holding an AWS Secret Access Key
	// +optional
	SecretAccessKeySecret *corev1.SecretKeySelector `json:"secretAccessKeySecret,omitempty"`

	// The name & key of a Kubernetes secret holding an AWS Session Token
	// +optional
	SessionTokenSecret *corev1.SecretKeySelector `json:"sessionTokenSecret,omitempty"`

	// The name & key of a Kubernetes secret holding an AWS credentials file
	// +optional
	CredentialsFileSecret *corev1.SecretKeySelector `json:"credentialsFileSecret,omitempty"`
}

type VolumeRepository struct {
	// This is a volumeSource for a volume that will be mounted to all solrNodes to store backups and load restores.
	// The data within the volume will be namespaced for this instance, so feel free to use the same volume for multiple clouds.
	// Since the volume will be mounted to all solrNodes, it must be able to be written from multiple pods.
	// If a PVC reference is given, the PVC must have `accessModes: - ReadWriteMany`.
	// Other options are to use a NFS volume.
	Source corev1.VolumeSource `json:"source"`

	// Select a custom directory name to mount the backup/restore data in the given volume.
	// If not specified, then the name of the solrcloud will be used by default.
	// +optional
	Directory string `json:"directory,omitempty"`
}

type SolrAddressabilityOptions struct {
	// External defines the way in which this SolrCloud nodes should be made addressable externally, from outside the Kubernetes cluster.
	// If none is provided, the Solr Cloud will not be made addressable externally.
	// +optional
	External *ExternalAddressability `json:"external,omitempty"`

	// PodPort defines the port to have the Solr Pod listen on.
	// Defaults to 8983
	// +optional
	PodPort int `json:"podPort,omitempty"`

	// CommonServicePort defines the port to have the common Solr service listen on.
	// Defaults to 80 (when not using TLS) or 443 (when using TLS)
	// +optional
	CommonServicePort int `json:"commonServicePort,omitempty"`

	// KubeDomain allows for the specification of an override of the default "cluster.local" Kubernetes cluster domain.
	// Only use this option if the Kubernetes cluster has been setup with a custom domain.
	// +optional
	KubeDomain string `json:"kubeDomain,omitempty"`
}

func (opts *SolrAddressabilityOptions) withDefaults(usesTLS bool, logger logr.Logger) (changed bool) {
	if opts.External != nil {
		changed = opts.External.withDefaults(usesTLS, logger)
	}
	if opts.PodPort == 0 {
		changed = true
		opts.PodPort = 8983
	}
	if opts.CommonServicePort == 0 {
		changed = true
		if usesTLS {
			opts.CommonServicePort = 443
		} else {
			opts.CommonServicePort = 80
		}
	}
	return changed
}

// ExternalAddressability defines the config for making Solr services available externally to kubernetes.
// Be careful when using LoadBalanced and includeNodes, as many IP addresses could be created if you are running many large solrClouds.
type ExternalAddressability struct {
	// The way in which this SolrCloud's service(s) should be made addressable externally.
	Method ExternalAddressabilityMethod `json:"method"`

	// Use the external address to advertise the SolrNode, defaults to false.
	//
	// If false, the external address will be available, however Solr (and clients using the CloudSolrClient in SolrJ) will only be aware of the internal URLs.
	// If true, Solr will startup with the hostname of the external address.
	//
	// NOTE: This option cannot be true when hideNodes is set to true. So it will be auto-set to false if that is the case.
	//
	// +optional
	UseExternalAddress bool `json:"useExternalAddress"`

	// Do not expose the common Solr service externally. This affects a single service.
	// Defaults to false.
	// +optional
	HideCommon bool `json:"hideCommon,omitempty"`

	// Do not expose each of the Solr Node services externally.
	// The number of services this affects could range from 1 (a headless service for ExternalDNS) to the number of Solr pods your cloud contains (individual node services for Ingress/LoadBalancer).
	// Defaults to false.
	// +optional
	HideNodes bool `json:"hideNodes,omitempty"`

	// Override the domainName provided as startup parameters to the operator, used by ingresses and externalDNS.
	// The common and/or node services will be addressable by unique names under the given domain.
	// e.g. given.domain.name.com -> default-example-solrcloud.given.domain.name.com
	//
	// For the LoadBalancer method, this field is optional and will only be used when useExternalAddress=true.
	// If used with the LoadBalancer method, you will need DNS routing to the LoadBalancer IP address through the url template given above.
	DomainName string `json:"domainName"`

	// Provide additional domainNames that the Ingress or ExternalDNS should listen on.
	// This option is ignored with the LoadBalancer method.
	// +optional
	AdditionalDomainNames []string `json:"additionalDomainNames,omitempty"`

	// NodePortOverride defines the port to have all Solr node service(s) listen on and advertise itself as if advertising through an Ingress or LoadBalancer.
	// This overrides the default usage of the podPort.
	//
	// This is option is only used when HideNodes=false, otherwise the the port each Solr Node will advertise itself with the podPort.
	// This option is also unavailable with the ExternalDNS method.
	//
	// If using method=Ingress, your ingress controller is required to listen on this port.
	// If your ingress controller is not listening on the podPort, then this option is required for solr to be addressable via an Ingress.
	//
	// Defaults to 80 (without TLS) or 443 (with TLS) if HideNodes=false and method=Ingress, otherwise this is optional.
	// +optional
	NodePortOverride int `json:"nodePortOverride,omitempty"`

	// IngressTLSTermination tells the SolrCloud Ingress to terminate TLS on incoming connections.
	//
	// This is option is only available when Method=Ingress, because ExternalDNS and LoadBalancer Services do not support TLS termination.
	// This option is also unavailable when the SolrCloud has TLS enabled via `spec.solrTLS`, in this case the Ingress cannot terminate TLS before reaching Solr.
	//
	// When using this option, the UseExternalAddress option will be disabled, since Solr cannot be running in HTTP mode and making internal requests in HTTPS.
	//
	// +optional
	IngressTLSTermination *SolrIngressTLSTermination `json:"ingressTLSTermination,omitempty"`
}

// ExternalAddressabilityMethod is a string enumeration type that enumerates
// all possible ways that a SolrCloud can be made addressable external to the kubernetes cluster.
// +kubebuilder:validation:Enum=Ingress;ExternalDNS
type ExternalAddressabilityMethod string

const (
	// Use an ingress to make the Solr service(s) externally addressable
	Ingress ExternalAddressabilityMethod = "Ingress"

	// Use ExternalDNS to make the Solr service(s) externally addressable
	ExternalDNS ExternalAddressabilityMethod = "ExternalDNS"

	// Make Solr service(s) type:LoadBalancer to make them externally addressable
	// NOTE: This option is not currently supported.
	LoadBalancer ExternalAddressabilityMethod = "LoadBalancer"
)

func (opts *ExternalAddressability) withDefaults(usesTLS bool, logger logr.Logger) (changed bool) {
	// You can't use an externalAddress for Solr Nodes if the Nodes are hidden externally
	if opts.UseExternalAddress && (opts.HideNodes || opts.IngressTLSTermination != nil) {
		changed = true
		opts.UseExternalAddress = false
	}

	// If the Ingress method is used, default the nodePortOverride to 80 or 443, since that is the port that most ingress controllers listen on.
	if !opts.HideNodes && opts.Method == Ingress && opts.NodePortOverride == 0 {
		changed = true
		if usesTLS {
			opts.NodePortOverride = 443
		} else {
			opts.NodePortOverride = 80
		}
	}
	// If a headless service is used, aka not using individual node services, then a nodePortOverride is not allowed.
	if !opts.UsesIndividualNodeServices() && opts.NodePortOverride > 0 {
		changed = true
		opts.NodePortOverride = 0
	}

	return changed
}

// SolrIngressTLSTermination defines how a SolrCloud should have TLS Termination enabled.
// Only one option can be provided.
//
// +kubebuilder:validation:MaxProperties=1
type SolrIngressTLSTermination struct {

	// UseDefaultTLSSecret determines whether the ingress should use the default TLS secret provided by the Ingress implementation.
	//
	// For example, using nginx: https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate
	//
	// +optional
	UseDefaultTLSSecret bool `json:"useDefaultTLSSecret,omitempty"`

	// TLSSecret defines a TLS Secret to use for TLS termination of all exposed addresses for this SolrCloud in the Ingress.
	//
	// +optional
	TLSSecret string `json:"tlsSecret,omitempty"`
}

type SolrUpdateStrategy struct {
	// Method defines the way in which SolrClouds should be updated when the podSpec changes.
	// +optional
	Method SolrUpdateMethod `json:"method,omitempty"`

	// Options for Solr Operator Managed rolling updates.
	// +optional
	ManagedUpdateOptions ManagedUpdateOptions `json:"managed,omitempty"`

	// Perform a scheduled restart on the given schedule, in CRON format.
	//
	// Multiple CRON syntaxes are supported
	//   - Standard CRON (e.g. "CRON_TZ=Asia/Seoul 0 6 * * ?")
	//   - Predefined Schedules (e.g. "@yearly", "@weekly", etc.)
	//   - Intervals (e.g. "@every 10h30m")
	//
	// For more information please check this reference:
	// https://pkg.go.dev/github.com/robfig/cron/v3?utm_source=godoc#hdr-CRON_Expression_Format
	//
	// +optional
	RestartSchedule string `json:"restartSchedule,omitempty"`
}

// SolrUpdateMethod is a string enumeration type that enumerates
// all possible ways that a SolrCloud can have rolling updates managed.
// +kubebuilder:validation:Enum=Managed;StatefulSet;Manual
type SolrUpdateMethod string

const (
	// Let the Solr Operator manage rolling updates to keep collections/shards available while updating pods in parallel.
	// This is the default option.
	ManagedUpdate SolrUpdateMethod = "Managed"

	// Use the default StatefulSet rolling updates logic. One pod at a time, starting with the highest ordinal.
	StatefulSetUpdate SolrUpdateMethod = "StatefulSet"

	// The Solr Operator and Kubernetes will not delete pods for updates. The user will be responsible for this.
	ManualUpdate SolrUpdateMethod = "Manual"
)

func (opts *SolrUpdateStrategy) withDefaults() (changed bool) {
	// You can't use an externalAddress for Solr Nodes if the Nodes are hidden externally
	if opts.Method == "" {
		changed = true
		opts.Method = ManagedUpdate
	}

	return changed
}

// ManagedUpdateOptions control the desired behavior of managed rolling update.
type ManagedUpdateOptions struct {

	// The maximum number of pods that can be unavailable during the update.
	// Value can be an absolute number (ex: 5) or a percentage of the desired number of pods (ex: 10%).
	// Absolute number is calculated from percentage by rounding down.
	// If the provided number is 0 or negative, then all pods will be allowed to be updated in unison.
	//
	// Defaults to 25%.
	//
	// +optional
	MaxPodsUnavailable *intstr.IntOrString `json:"maxPodsUnavailable,omitempty"`

	// The maximum number of replicas for each shard that can be unavailable during the update.
	// Value can be an absolute number (ex: 5) or a percentage of replicas in a shard (ex: 25%).
	// Absolute number is calculated from percentage by rounding down.
	// If the provided number is 0 or negative, then all replicas will be allowed to be updated in unison.
	//
	// Defaults to 1.
	//
	// +optional
	MaxShardReplicasUnavailable *intstr.IntOrString `json:"maxShardReplicasUnavailable,omitempty"`
}

type SolrAvailabilityOptions struct {
	// Define PodDisruptionBudget(s) to ensure availability of Solr
	// +optional
	PodDisruptionBudget SolrPodDisruptionBudgetOptions `json:"podDisruptionBudget,omitempty"`
}

type SolrPodDisruptionBudgetOptions struct {
	// What method should be used when creating PodDisruptionBudget(s)
	// +kubebuilder:default=true
	Enabled *bool `json:"enabled"`

	// What method should be used when creating PodDisruptionBudget(s)
	// +kubebuilder:default=ClusterWide
	Method SolrPodDisruptionBudgetMethod `json:"method,omitempty"`
}

// SolrPodDisruptionBudgetMethod is a string enumeration type that enumerates
// all possible ways that a SolrCloud can have PodDisruptionBudgets managed.
// +kubebuilder:validation:Enum=ClusterWide
type SolrPodDisruptionBudgetMethod string

const (
	// ClusterWidePDB will result in a single cluster-wide PDB being created to ensure availability of the SolrCloud.
	// This will not take replica/shard readiness into account.
	ClusterWidePDB SolrPodDisruptionBudgetMethod = "ClusterWide"
)

// ZookeeperRef defines the zookeeper ensemble for solr to connect to
// If no ConnectionString is provided, the solr-cloud controller will create and manage an internal ensemble
type ZookeeperRef struct {
	// A zookeeper ensemble that is run independently of the solr operator
	// If an externalConnectionString is provided, but no internalConnectionString is, the external will be used as the internal
	// +optional
	ConnectionInfo *ZookeeperConnectionInfo `json:"connectionInfo,omitempty"`

	// Create a new Zookeeper Ensemble with the following spec
	// Note: This option will not allow the SolrCloud to run across kube-clusters.
	// Note: Requires
	//   - The zookeeperOperator flag to be provided to the Solr Operator
	//   - A zookeeper operator to be running
	// +optional
	ProvidedZookeeper *ZookeeperSpec `json:"provided,omitempty"`
}

func (ref *ZookeeperRef) withDefaults() (changed bool) {
	if ref.ProvidedZookeeper == nil && ref.ConnectionInfo == nil {
		changed = true
		ref.ProvidedZookeeper = &ZookeeperSpec{}
	} else if ref.ConnectionInfo != nil {
		if ref.ProvidedZookeeper != nil {
			ref.ProvidedZookeeper = nil
			changed = true
		}
		changed = ref.ConnectionInfo.withDefaults() || changed
	}
	if ref.ProvidedZookeeper != nil {
		changed = ref.ProvidedZookeeper.WithDefaults() || changed
	}
	return changed
}

func (ref *ZookeeperRef) GetACLs() (allACL *ZookeeperACL, readOnlyACL *ZookeeperACL) {
	if ref.ConnectionInfo != nil {
		allACL = ref.ConnectionInfo.AllACL
		readOnlyACL = ref.ConnectionInfo.ReadOnlyACL
	} else if ref.ProvidedZookeeper != nil {
		allACL = ref.ProvidedZookeeper.AllACL
		readOnlyACL = ref.ProvidedZookeeper.ReadOnlyACL
	}
	return
}

// ZookeeperSpec defines the internal zookeeper ensemble to run with the given spec
type ZookeeperSpec struct {

	// Number of members to create up for the ZK ensemble
	// Defaults to 3
	// +optional
	Replicas *int32 `json:"replicas,omitempty"`

	// Image of Zookeeper to run
	// +optional
	Image *ContainerImage `json:"image,omitempty"`

	// Persistence is the configuration for zookeeper persistent layer.
	// PersistentVolumeClaimSpec and VolumeReclaimPolicy can be specified in here.
	// At anypoint only one of Persistence or Ephemeral should be present in the manifest
	// +optional
	Persistence *ZKPersistence `json:"persistence,omitempty"`

	// Ephemeral is the configuration which helps create ephemeral storage
	// At anypoint only one of Persistence or Ephemeral should be present in the manifest
	// +optional
	Ephemeral *ZKEphemeral `json:"ephemeral,omitempty"`

	// Customization options for the Zookeeper Pod
	// +optional
	ZookeeperPod ZookeeperPodPolicy `json:"zookeeperPodPolicy,omitempty"`

	// The ChRoot to connect solr at
	// +optional
	ChRoot string `json:"chroot,omitempty"`

	// ZooKeeper ACL to use when connecting with ZK.
	// This ACL should have ALL permission in the given chRoot.
	// +optional
	AllACL *ZookeeperACL `json:"acl,omitempty"`

	// ZooKeeper ACL to use when connecting with ZK for reading operations.
	// This ACL should have READ permission in the given chRoot.
	// +optional
	ReadOnlyACL *ZookeeperACL `json:"readOnlyAcl,omitempty"`

	// Additional Zookeeper Configuration settings
	// +optional
	Config ZookeeperConfig `json:"config,omitempty"`

	// Probes specifies the timeout values for the Readiness and Liveness Probes
	// for the zookeeper pods.
	// +optional
	Probes *zkApi.Probes `json:"probes,omitempty"`
}

type ZKPersistence struct {
	// VolumeReclaimPolicy is a zookeeper operator configuration. If it's set to Delete,
	// the corresponding PVCs will be deleted by the operator when zookeeper cluster is deleted.
	// The default value is Retain.
	VolumeReclaimPolicy VolumeReclaimPolicy `json:"reclaimPolicy,omitempty"`
	// PersistentVolumeClaimSpec is the spec to describe PVC for the container
	// This field is optional. If no PVC is specified default persistentvolume
	// will get created.
	PersistentVolumeClaimSpec corev1.PersistentVolumeClaimSpec `json:"spec,omitempty"`
	// Annotations specifies the annotations to attach to pvc the operator
	// creates.
	Annotations map[string]string `json:"annotations,omitempty"`
}

type ZKEphemeral struct {
	//EmptyDirVolumeSource is optional and this will create the emptydir volume
	//It has two parameters Medium and SizeLimit which are optional as well
	//Medium specifies What type of storage medium should back this directory.
	//SizeLimit specifies Total amount of local storage required for this EmptyDir volume.
	EmptyDirVolumeSource corev1.EmptyDirVolumeSource `json:"emptydirvolumesource,omitempty"`
}

// ZookeeperConfig is the current configuration of each Zookeeper node, which
// sets these values in the config-map
type ZookeeperConfig struct {
	// InitLimit is the amount of time, in ticks, to allow followers to connect
	// and sync to a leader.
	//
	// Default value is 10.
	InitLimit int `json:"initLimit,omitempty"`

	// TickTime is the length of a single tick, which is the basic time unit used
	// by Zookeeper, as measured in milliseconds
	//
	// The default value is 2000.
	TickTime int `json:"tickTime,omitempty"`

	// SyncLimit is the amount of time, in ticks, to allow followers to sync with
	// Zookeeper.
	//
	// The default value is 2.
	SyncLimit int `json:"syncLimit,omitempty"`

	// Clients can submit requests faster than ZooKeeper can process them, especially
	// if there are a lot of clients. Zookeeper will throttle Clients so that requests
	// won't exceed global outstanding limit.
	//
	// The default value is 1000
	GlobalOutstandingLimit int `json:"globalOutstandingLimit,omitempty"`

	// To avoid seeks ZooKeeper allocates space in the transaction log file in
	// blocks of preAllocSize kilobytes
	//
	// The default value is 64M
	PreAllocSize int `json:"preAllocSize,omitempty"`

	// ZooKeeper records its transactions using snapshots and a transaction log
	// The number of transactions recorded in the transaction log before a snapshot
	// can be taken is determined by snapCount
	//
	// The default value is 100,000
	SnapCount int `json:"snapCount,omitempty"`

	// Zookeeper maintains an in-memory list of last committed requests for fast
	// synchronization with followers
	//
	// The default value is 500
	CommitLogCount int `json:"commitLogCount,omitempty"`

	// Snapshot size limit in Kb
	//
	// The defult value is 4GB
	SnapSizeLimitInKb int `json:"snapSizeLimitInKb,omitempty"`

	// Limits the total number of concurrent connections that can be made to a
	//zookeeper server
	//
	// The defult value is 0, indicating no limit
	MaxCnxns int `json:"maxCnxns,omitempty"`

	// Limits the number of concurrent connections that a single client, identified
	// by IP address, may make to a single member of the ZooKeeper ensemble.
	//
	// The default value is 60
	MaxClientCnxns int `json:"maxClientCnxns,omitempty"`

	// The minimum session timeout in milliseconds that the server will allow the
	// client to negotiate
	//
	// The default value is 4000
	MinSessionTimeout int `json:"minSessionTimeout,omitempty"`

	// The maximum session timeout in milliseconds that the server will allow the
	// client to negotiate.
	//
	// The default value is 40000
	MaxSessionTimeout int `json:"maxSessionTimeout,omitempty"`

	// Retain the snapshots according to retain count
	//
	// The default value is 3
	AutoPurgeSnapRetainCount int `json:"autoPurgeSnapRetainCount,omitempty"`

	// The time interval in hours for which the purge task has to be triggered
	//
	// Disabled by default
	AutoPurgePurgeInterval int `json:"autoPurgePurgeInterval,omitempty"`

	// QuorumListenOnAllIPs when set to true the ZooKeeper server will listen for
	// connections from its peers on all available IP addresses, and not only the
	// address configured in the server list of the configuration file. It affects
	// the connections handling the ZAB protocol and the Fast Leader Election protocol.
	//
	// The default value is false.
	QuorumListenOnAllIPs bool `json:"quorumListenOnAllIPs,omitempty"`

	// key-value map of additional zookeeper configuration parameters
	// +kubebuilder:pruning:PreserveUnknownFields
	// +optional
	AdditionalConfig map[string]string `json:"additionalConfig,omitempty"`
}

func (z *ZookeeperSpec) WithDefaults() (changed bool) {
	if z.Replicas == nil {
		changed = true
		r := DefaultZkReplicas
		z.Replicas = &r
	}

	if z.Image == nil {
		z.Image = &ContainerImage{}
	}
	changed = z.Image.withDefaults(DefaultZkRepo, DefaultZkVersion, corev1.PullIfNotPresent) || changed

	if z.Persistence != nil {
		if z.Persistence.VolumeReclaimPolicy == "" {
			z.Persistence.VolumeReclaimPolicy = DefaultZkVolumeReclaimPolicy
			changed = true
		}

		if len(z.Persistence.PersistentVolumeClaimSpec.AccessModes) == 0 {
			z.Persistence.PersistentVolumeClaimSpec.AccessModes = []corev1.PersistentVolumeAccessMode{
				corev1.ReadWriteOnce,
			}
			changed = true
		}

		if len(z.Persistence.PersistentVolumeClaimSpec.Resources.Requests) == 0 {
			z.Persistence.PersistentVolumeClaimSpec.Resources.Requests = corev1.ResourceList{
				corev1.ResourceStorage: resource.MustParse(DefaultZkStorage),
			}
			changed = true
		}
	}

	if z.ChRoot == "" {
		changed = true
		z.ChRoot = "/"
	} else if !strings.HasPrefix(z.ChRoot, "/") {
		changed = true
		z.ChRoot = "/" + z.ChRoot
	}
	return changed
}

// ZookeeperPodPolicy defines the common pod configuration for Pods, including when used
// in deployments, stateful-sets, etc.
type ZookeeperPodPolicy struct {
	// The scheduling constraints on pods.
	// +optional
	Affinity *corev1.Affinity `json:"affinity,omitempty"`

	// Node Selector to be added on pods.
	// +optional
	NodeSelector map[string]string `json:"nodeSelector,omitempty"`

	// Tolerations to be added on pods.
	// +optional
	Tolerations []corev1.Toleration `json:"tolerations,omitempty"`

	// List of environment variables to set in the main ZK container.
	// +optional
	Env []corev1.EnvVar `json:"env,omitempty"`

	// Resources is the resource requirements for the Zookeeper container.
	// +optional
	Resources corev1.ResourceRequirements `json:"resources,omitempty"`

	// Optional Service Account to run the zookeeper pods under.
	// +optional
	ServiceAccountName string `json:"serviceAccountName,omitempty"`

	// Labels specifies the labels to attach to pods the operator creates for
	// the zookeeper cluster.
	// +optional
	Labels map[string]string `json:"labels,omitempty"`

	// Annotations specifies the annotations to attach to zookeeper pods
	// creates.
	// +optional
	Annotations map[string]string `json:"annotations,omitempty"`

	// SecurityContext specifies the security context for the entire zookeeper pod
	// More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context
	// +optional
	SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"`

	// TerminationGracePeriodSeconds is the amount of time that kubernetes will
	// give for a zookeeper pod instance to shutdown normally.
	// The default value is 30.
	// +optional
	// +kubebuilder:validation:Minimum=0
	TerminationGracePeriodSeconds int64 `json:"terminationGracePeriodSeconds,omitempty"`

	// ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images
	// +optional
	ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
}

// SolrCloudStatus defines the observed state of SolrCloud
type SolrCloudStatus struct {
	// SolrNodes contain the statuses of each solr node running in this solr cloud.
	//+listType:=map
	//+listMapKey:=name
	SolrNodes []SolrNodeStatus `json:"solrNodes"`

	// Replicas is the number of desired replicas in the cluster
	// +kubebuilder:validation:Minimum=0
	// +kubebuilder:default=0
	Replicas int32 `json:"replicas"`

	// PodSelector for SolrCloud pods, required by the HPA
	PodSelector string `json:"podSelector"`

	// ReadyReplicas is the number of ready replicas in the cluster
	// +kubebuilder:validation:Minimum=0
	// +kubebuilder:default=0
	ReadyReplicas int32 `json:"readyReplicas"`

	// UpToDateNodes is the number of Solr Node pods that are running the latest pod spec
	// +kubebuilder:validation:Minimum=0
	// +kubebuilder:default=0
	UpToDateNodes int32 `json:"upToDateNodes"`

	// The version of solr that the cloud is running
	Version string `json:"version"`

	// The version of solr that the cloud is meant to be running.
	// Will only be provided when the cloud is migrating between versions
	// +optional
	TargetVersion string `json:"targetVersion,omitempty"`

	// InternalCommonAddress is the internal common http address for all solr nodes
	InternalCommonAddress string `json:"internalCommonAddress"`

	// ExternalCommonAddress is the external common http address for all solr nodes.
	// Will only be provided when an ingressUrl is provided for the cloud
	// +optional
	ExternalCommonAddress *string `json:"externalCommonAddress,omitempty"`

	// ZookeeperConnectionInfo is the information on how to connect to the used Zookeeper
	ZookeeperConnectionInfo ZookeeperConnectionInfo `json:"zookeeperConnectionInfo"`

	// BackupRestoreReady announces whether the solrCloud has the backupRestorePVC mounted to all pods
	// and therefore is ready for backups and restores.
	// +optional
	BackupRestoreReady bool `json:"backupRestoreReady"`

	// BackupRepositoriesAvailable lists the backupRepositories specified in the SolrCloud and whether they are available across all Pods.
	// +optional
	BackupRepositoriesAvailable map[string]bool `json:"backupRepositoriesAvailable,omitempty"`
}

// SolrNodeStatus is the status of a solrNode in the cloud, with readiness status
// and internal and external addresses
type SolrNodeStatus struct {
	// The name of the pod running the node
	Name string `json:"name"`

	// The name of the Kubernetes Node which the pod is running on
	NodeName string `json:"nodeName"`

	// An address the node can be connected to from within the Kube cluster
	InternalAddress string `json:"internalAddress"`

	// An address the node can be connected to from outside of the Kube cluster
	// Will only be provided when an ingressUrl is provided for the cloud
	// +optional
	ExternalAddress string `json:"externalAddress,omitempty"`

	// Is the node up and running
	Ready bool `json:"ready"`

	// The version of solr that the node is running
	Version string `json:"version"`

	// This Solr Node pod is using the latest version of solrcloud pod spec.
	SpecUpToDate bool `json:"specUpToDate"`

	// This Solr Node pod is scheduled for deletion
	// +optional
	ScheduledForDeletion bool `json:"scheduledForDeletion"`
}

//+kubebuilder:object:root=true
//+kubebuilder:resource:scope=Namespaced
//+kubebuilder:resource:shortName=solr
//+kubebuilder:categories=all
//+kubebuilder:subresource:status
//+kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.readyReplicas,selectorpath=.status.podSelector
//+kubebuilder:storageversion
//+kubebuilder:printcolumn:name="Version",type="string",JSONPath=".status.version",description="Solr Version of the cloud"
//+kubebuilder:printcolumn:name="TargetVersion",type="string",JSONPath=".status.targetVersion",description="Target Solr Version of the cloud"
//+kubebuilder:printcolumn:name="DesiredNodes",type="integer",JSONPath=".spec.replicas",description="Number of solr nodes configured to run in the cloud"
//+kubebuilder:printcolumn:name="Nodes",type="integer",JSONPath=".status.replicas",description="Number of solr nodes running"
//+kubebuilder:printcolumn:name="ReadyNodes",type="integer",JSONPath=".status.readyReplicas",description="Number of solr nodes connected to the cloud"
//+kubebuilder:printcolumn:name="UpToDateNodes",type="integer",JSONPath=".status.upToDateNodes",description="Number of solr nodes running the latest SolrCloud pod spec"
//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"

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

	Spec   SolrCloudSpec   `json:"spec,omitempty"`
	Status SolrCloudStatus `json:"status,omitempty"`
}

// WithDefaults set default values when not defined in the spec.
func (sc *SolrCloud) WithDefaults(logger logr.Logger) bool {
	return sc.Spec.withDefaults(logger)
}

func (sc *SolrCloud) GetAllSolrPodNames() []string {
	replicas := 1
	if sc.Spec.Replicas != nil {
		replicas = int(*sc.Spec.Replicas)
	}
	podNames := make([]string, replicas)
	statefulSetName := sc.StatefulSetName()
	for i := range podNames {
		podNames[i] = fmt.Sprintf("%s-%d", statefulSetName, i)
	}
	return podNames
}

func (sc *SolrCloud) BasicAuthSecretName() string {
	if sc.Spec.SolrSecurity != nil && sc.Spec.SolrSecurity.BasicAuthSecret != "" {
		return sc.Spec.SolrSecurity.BasicAuthSecret
	} else {
		return fmt.Sprintf("%s-solrcloud-basic-auth", sc.Name)
	}
}

func (sc *SolrCloud) SecurityBootstrapSecretName() string {
	return fmt.Sprintf("%s-solrcloud-security-bootstrap", sc.Name)
}

// ConfigMapName returns the name of the cloud config-map
func (sc *SolrCloud) ConfigMapName() string {
	return fmt.Sprintf("%s-solrcloud-configmap", sc.GetName())
}

// StatefulSetName returns the name of the statefulset for the cloud
func (sc *SolrCloud) StatefulSetName() string {
	return fmt.Sprintf("%s-solrcloud", sc.GetName())
}

// CommonServiceName returns the name of the common service for the cloud
func (sc *SolrCloud) CommonServiceName() string {
	return fmt.Sprintf("%s-solrcloud-common", sc.GetName())
}

// InternalURLForCloud returns the name of the common service for the cloud
func InternalURLForCloud(sc *SolrCloud) string {
	return fmt.Sprintf("%s://%s-solrcloud-common.%s%s", sc.UrlScheme(false), sc.Name, sc.Namespace, sc.CommonPortSuffix(false))
}

// HeadlessServiceName returns the name of the headless service for the cloud
func (sc *SolrCloud) HeadlessServiceName() string {
	return fmt.Sprintf("%s-solrcloud-headless", sc.GetName())
}

// CommonIngressName returns the name of the common ingress for the cloud
func (sc *SolrCloud) CommonIngressName() string {
	return fmt.Sprintf("%s-solrcloud-common", sc.GetName())
}

// ProvidedZookeeperName returns the provided zk cluster
func (sc *SolrCloud) ProvidedZookeeperName() string {
	return fmt.Sprintf("%s-solrcloud-zookeeper", sc.GetName())
}

// ProvidedZookeeperAddress returns the client address of the provided zk cluster
func (sc *SolrCloud) ProvidedZookeeperAddress() string {
	return fmt.Sprintf("%s-solrcloud-zookeeper-client:2181", sc.GetName())
}

// ZkConnectionString returns the zkConnectionString for the cloud
func (sc *SolrCloud) ZkConnectionString() string {
	return sc.Status.ZkConnectionString()
}
func (scs SolrCloudStatus) ZkConnectionString() string {
	return scs.ZookeeperConnectionInfo.ZkConnectionString()
}
func (scs SolrCloudStatus) DissectZkInfo() (zkConnectionString string, zkServer string, zkChRoot string) {
	zkConnectionString = scs.ZookeeperConnectionInfo.ZkConnectionString()
	zkParts := strings.SplitN(zkConnectionString, "/", 2)
	zkServer = zkParts[0]
	zkChRoot = "/" + zkParts[1]

	return zkConnectionString, zkServer, zkChRoot
}

func (zkInfo ZookeeperConnectionInfo) ZkConnectionString() string {
	return zkInfo.InternalConnectionString + zkInfo.ChRoot
}

// UsesHeadlessService returns whether the given solrCloud requires a headless service to be created for it.
// solrCloud: SolrCloud instance
func (sc *SolrCloud) UsesHeadlessService() bool {
	return !sc.Spec.SolrAddressability.External.UsesIndividualNodeServices()
}

// UsesIndividualNodeServices returns whether the given solrCloud requires a individual node services to be created for it.
// solrCloud: SolrCloud instance
func (sc *SolrCloud) UsesIndividualNodeServices() bool {
	return sc.Spec.SolrAddressability.External.UsesIndividualNodeServices()
}

func (extOpts *ExternalAddressability) UsesIndividualNodeServices() bool {
	// LoadBalancer and Ingress will not work with headless services if each pod needs to be exposed externally.
	return extOpts != nil && !extOpts.HideNodes && (extOpts.Method == Ingress || extOpts.Method == LoadBalancer)
}

func (sc *SolrCloud) CommonExternalPrefix() string {
	return fmt.Sprintf("%s-%s-solrcloud", sc.Namespace, sc.Name)
}

func (sc *SolrCloud) NodeIngressPrefix(nodeName string) string {
	return fmt.Sprintf("%s-%s", sc.Namespace, nodeName)
}

func (sc *SolrCloud) ExternalDnsDomain(domainName string) string {
	return fmt.Sprintf("%s.%s", sc.Namespace, domainName)
}

func (sc *SolrCloud) customKubeDomain() string {
	if sc.Spec.SolrAddressability.KubeDomain != "" {
		return ".svc." + sc.Spec.SolrAddressability.KubeDomain
	} else {
		return ""
	}
}

func (sc *SolrCloud) NodeHeadlessUrl(nodeName string, withPort bool) (url string) {
	url = fmt.Sprintf("%s.%s.%s", nodeName, sc.HeadlessServiceName(), sc.Namespace) + sc.customKubeDomain()
	if withPort {
		url += sc.NodePortSuffix(false)
	}
	return url
}

func (sc *SolrCloud) NodeServiceUrl(nodeName string, withPort bool) (url string) {
	url = fmt.Sprintf("%s.%s", nodeName, sc.Namespace) + sc.customKubeDomain()
	if withPort {
		url += sc.NodePortSuffix(false)
	}
	return url
}

func (sc *SolrCloud) CommonPortSuffix(external bool) string {
	return sc.PortToSuffix(sc.Spec.SolrAddressability.CommonServicePort, external)
}

func (sc *SolrCloud) NodePortSuffix(external bool) string {
	return sc.PortToSuffix(sc.NodePort(), external)
}

func (sc *SolrCloud) NodePort() int {
	port := sc.Spec.SolrAddressability.PodPort
	external := sc.Spec.SolrAddressability.External
	// The nodePort is different than the podPort ONLY if the nodes are exposed externally and a nodePortOverride has been set.
	if external.UsesIndividualNodeServices() && external.NodePortOverride > 0 {
		port = sc.Spec.SolrAddressability.External.NodePortOverride
	}
	return port
}

func (sc *SolrCloud) PortToSuffix(port int, external bool) string {
	suffix := ""
	if sc.UrlScheme(external) == "https" {
		if port != 443 {
			suffix = ":" + strconv.Itoa(port)
		}
	} else {
		if port != 80 {
			suffix = ":" + strconv.Itoa(port)
		}
	}
	return suffix
}

func (sc *SolrCloud) InternalNodeUrl(nodeName string, withPort bool) string {
	if sc.UsesHeadlessService() {
		return sc.NodeHeadlessUrl(nodeName, withPort)
	} else if sc.UsesIndividualNodeServices() {
		return sc.NodeServiceUrl(nodeName, withPort)
	} else {
		return ""
	}
}

func (sc *SolrCloud) InternalCommonUrl(withPort bool) (url string) {
	url = fmt.Sprintf("%s.%s", sc.CommonServiceName(), sc.Namespace) + sc.customKubeDomain()
	if withPort {
		url += sc.CommonPortSuffix(false)
	}
	return url
}

func (sc *SolrCloud) ExternalNodeUrl(nodeName string, domainName string, withPort bool) (url string) {
	if sc.Spec.SolrAddressability.External.Method == Ingress {
		url = fmt.Sprintf("%s.%s", sc.NodeIngressPrefix(nodeName), domainName)
	} else if sc.Spec.SolrAddressability.External.Method == ExternalDNS {
		url = fmt.Sprintf("%s.%s", nodeName, sc.ExternalDnsDomain(domainName))
	}
	// TODO: Add LoadBalancer stuff here

	if withPort && sc.Spec.SolrAddressability.External.Method != Ingress {
		// Ingress does not require a port, since the port is whatever the ingress is listening on (80 and 443)
		url += sc.NodePortSuffix(true)
	}
	return url
}

func (sc *SolrCloud) ExternalCommonUrl(domainName string, withPort bool) (url string) {
	if sc.Spec.SolrAddressability.External.Method == Ingress {
		url = fmt.Sprintf("%s.%s", sc.CommonExternalPrefix(), domainName)
	} else if sc.Spec.SolrAddressability.External.Method == ExternalDNS {
		url = fmt.Sprintf("%s.%s", sc.CommonServiceName(), sc.ExternalDnsDomain(domainName))
	}
	// TODO: Add LoadBalancer stuff here

	if withPort && sc.Spec.SolrAddressability.External.Method != Ingress {
		// Ingress does not require a port, since the port is whatever the ingress is listening on (80 and 443)
		url += sc.CommonPortSuffix(true)
	}
	return url
}

func (ea *ExternalAddressability) HasIngressTLSTermination() bool {
	if ea != nil && ea.Method == Ingress && ea.IngressTLSTermination != nil {
		return ea.IngressTLSTermination.UseDefaultTLSSecret || ea.IngressTLSTermination.TLSSecret != ""
	}
	return false
}

func (sc *SolrCloud) UrlScheme(external bool) string {
	urlScheme := "http"
	if sc.Spec.SolrTLS != nil {
		urlScheme = "https"
	} else if external && sc.Spec.SolrAddressability.External.HasIngressTLSTermination() {
		urlScheme = "https"
	}
	return urlScheme
}

func (sc *SolrCloud) AdvertisedNodeHost(nodeName string) string {
	external := sc.Spec.SolrAddressability.External
	if external != nil && external.UseExternalAddress {
		return sc.ExternalNodeUrl(nodeName, sc.Spec.SolrAddressability.External.DomainName, false)
	} else {
		return sc.InternalNodeUrl(nodeName, false)
	}
}

func (sc *SolrCloud) UsesPersistentStorage() bool {
	return sc.Spec.StorageOptions.PersistentStorage != nil
}

func (sc *SolrCloud) DataVolumeName() string {
	// Set the default name of the pvc
	if sc.Spec.StorageOptions.PersistentStorage != nil &&
		sc.Spec.StorageOptions.PersistentStorage.PersistentVolumeClaimTemplate.ObjectMeta.Name != "" {
		return sc.Spec.StorageOptions.PersistentStorage.PersistentVolumeClaimTemplate.ObjectMeta.Name
	} else {
		return "data"
	}
}

func (sc *SolrCloud) SharedLabels() map[string]string {
	return sc.SharedLabelsWith(map[string]string{})
}

func (sc *SolrCloud) SharedLabelsWith(labels map[string]string) map[string]string {
	newLabels := map[string]string{}

	if labels != nil {
		for k, v := range labels {
			newLabels[k] = v
		}
	}

	newLabels["solr-cloud"] = sc.Name
	return newLabels
}

//+kubebuilder:object:root=true

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

func init() {
	SchemeBuilder.Register(&SolrCloud{}, &SolrCloudList{})
}

// +kubebuilder:validation:Enum=None;Want;Need
type ClientAuthType string

const (
	None ClientAuthType = "None"
	Want ClientAuthType = "Want"
	Need ClientAuthType = "Need"
)

type MountedTLSDirectory struct {
	// The path on the main Solr container where the TLS files are mounted by some external agent or CSI Driver
	Path string `json:"path"`

	// Override the name of the keystore file; no default, if you don't supply this setting, then the corresponding
	// env vars and Java system properties will not be configured for the pod template
	// +optional
	KeystoreFile string `json:"keystoreFile,omitempty"`

	// Override the name of the keystore password file; defaults to keystore-password
	// +optional
	KeystorePasswordFile string `json:"keystorePasswordFile,omitempty"`

	// Override the name of the truststore file; no default, if you don't supply this setting, then the corresponding
	// env vars and Java system properties will not be configured for the pod template
	// +optional
	TruststoreFile string `json:"truststoreFile,omitempty"`

	// Override the name of the truststore password file; defaults to the same value as the KeystorePasswordFile
	// +optional
	TruststorePasswordFile string `json:"truststorePasswordFile,omitempty"`
}

type SolrTLSOptions struct {
	// TLS Secret containing a pkcs12 keystore; required for Solr pods unless mountedTLSDir is used
	// +optional
	PKCS12Secret *corev1.SecretKeySelector `json:"pkcs12Secret,omitempty"`

	// Secret containing the key store password; this field is required unless mountedTLSDir is used, as most JVMs do not support pkcs12 keystores without a password
	// +optional
	KeyStorePasswordSecret *corev1.SecretKeySelector `json:"keyStorePasswordSecret,omitempty"`

	// TLS Secret containing a pkcs12 truststore; if not provided, then the keystore and password are used for the truststore
	// The specified key is used as the truststore file name when mounted into Solr pods
	// +optional
	TrustStoreSecret *corev1.SecretKeySelector `json:"trustStoreSecret,omitempty"`

	// Secret containing the trust store password; if not provided the keyStorePassword will be used
	// +optional
	TrustStorePasswordSecret *corev1.SecretKeySelector `json:"trustStorePasswordSecret,omitempty"`

	// Determines the client authentication method, either None, Want, or Need;
	// this affects K8s ability to call liveness / readiness probes so use cautiously.
	// Only applies for server certificates, has no effect on client certificates
	// +kubebuilder:default=None
	ClientAuth ClientAuthType `json:"clientAuth,omitempty"`

	// Verify client's hostname during SSL handshake
	// Only applies for server configuration
	// +optional
	VerifyClientHostname bool `json:"verifyClientHostname,omitempty"`

	// TLS certificates contain host/ip "peer name" information that is validated by default.
	// +optional
	CheckPeerName bool `json:"checkPeerName,omitempty"`

	// Opt-in flag to restart Solr pods after TLS secret updates, such as if the cert is renewed; default is false.
	// This option only applies when using the `spec.solrTLS.pkcs12Secret` option; when using the `spec.solrTLS.mountedTLSDir` option,
	// you need to ensure pods get restarted before the certs expire, see `spec.updateStrategy.restartSchedule` for scheduling restarts.
	// +optional
	RestartOnTLSSecretUpdate bool `json:"restartOnTLSSecretUpdate,omitempty"`

	// Used to specify a path where the keystore, truststore, and password files for the TLS certificate are mounted by an external agent or CSI driver.
	// This option is typically used with `spec.updateStrategy.restartSchedule` to restart Solr pods before the mounted TLS cert expires.
	// +optional
	MountedTLSDir *MountedTLSDirectory `json:"mountedTLSDir,omitempty"`
}

// +kubebuilder:validation:Enum=Basic
type AuthenticationType string

const (
	Basic AuthenticationType = "Basic"
)

type SolrSecurityOptions struct {
	// Indicates the authentication plugin type that is being used by Solr; for now only "Basic" is supported by the
	// Solr operator but support for other authentication plugins may be added in the future.
	AuthenticationType AuthenticationType `json:"authenticationType,omitempty"`

	// Secret (kubernetes.io/basic-auth) containing credentials the operator should use for API requests to secure Solr pods.
	// If you provide this secret, then the operator assumes you've also configured your own security.json file and
	// uploaded it to Solr. If you change the password for this user using the Solr security API, then you *must* update
	// the secret with the new password or the operator will be  locked out of Solr and API requests will fail,
	// ultimately causing a CrashBackoffLoop for all pods if probe endpoints are secured (see 'probesRequireAuth' setting).
	//
	// If you don't supply this secret, then the operator creates a kubernetes.io/basic-auth secret containing the password
	// for the "k8s-oper" user. All API requests from the operator are made as the "k8s-oper" user, which is configured
	// with read-only access to a minimal set of endpoints. In addition, the operator bootstraps a default security.json
	// file and credentials for two additional users: admin and solr. The 'solr' user has basic read access to Solr
	// resources. Once the security.json is bootstrapped, the operator will not update it! You're expected to use the
	// 'admin' user to access the Security API to make further changes. It's strictly a bootstrapping operation.
	// +optional
	BasicAuthSecret string `json:"basicAuthSecret,omitempty"`

	// Flag to indicate if the configured HTTP endpoint(s) used for the probes require authentication; defaults
	// to false. If you set to true, then probes will use a local command on the main container to hit the secured
	// endpoints with credentials sourced from an env var instead of HTTP directly.
	// +optional
	ProbesRequireAuth bool `json:"probesRequireAuth,omitempty"`

	// Configure a user-provided security.json from a secret to allow for advanced security config.
	// If not specified, the operator bootstraps a security.json with basic auth enabled.
	// This is a bootstrapping config only; once Solr is initialized, the security config should be managed by the security API.
	// +optional
	BootstrapSecurityJson *corev1.SecretKeySelector `json:"bootstrapSecurityJson,omitempty"`
}
