/*
Copyright 2020 The Jetstack cert-manager 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.
*/

package options

import (
	"strings"

	"github.com/spf13/pflag"
	cliflag "k8s.io/component-base/cli/flag"
)

type WebhookOptions struct {
	ListenPort  int
	HealthzPort int

	// Path to TLS certificate and private key on disk.
	// Both must be specified if either is.
	// May not be specified if DynamicServingCASecretNamespace and
	// DynamicServingCASecretName are set.
	TLSCertFile string
	TLSKeyFile  string

	// Namespace and name of the Secret resource containing the TLS certificate
	// used as a CA to sign dynamic serving certificates.
	// Both must be specified if either is.
	// May not be specified if TLSCertFile and TLSKeyFile are set.
	DynamicServingCASecretNamespace string
	DynamicServingCASecretName      string
	// List of DNSNames that must be present on serving certificates.
	DynamicServingDNSNames []string

	// Optional path to the kubeconfig used to connect to the apiserver when
	// using the 'dynamic serving' certificate sources.
	// If not specified, in cluster config will be used.
	Kubeconfig string

	// TLSCipherSuites is the list of allowed cipher suites for the server.
	// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
	TLSCipherSuites []string

	// MinTLSVersion is the minimum TLS version supported.
	// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
	MinTLSVersion string
}

func (o *WebhookOptions) AddFlags(fs *pflag.FlagSet) {
	// TODO: rename secure-port to listen-port
	fs.IntVar(&o.ListenPort, "secure-port", 6443, "port number to listen on for secure TLS connections")
	fs.IntVar(&o.HealthzPort, "healthz-port", 6080, "port number to listen on for insecure healthz connections")
	fs.StringVar(&o.TLSCertFile, "tls-cert-file", "", "path to the file containing the TLS certificate to serve with")
	fs.StringVar(&o.TLSKeyFile, "tls-private-key-file", "", "path to the file containing the TLS private key to serve with")
	fs.StringVar(&o.DynamicServingCASecretNamespace, "dynamic-serving-ca-secret-namespace", "", "namespace of the secret used to store the CA that signs serving certificates")
	fs.StringVar(&o.DynamicServingCASecretName, "dynamic-serving-ca-secret-name", "", "name of the secret used to store the CA that signs serving certificates certificates")
	fs.StringSliceVar(&o.DynamicServingDNSNames, "dynamic-serving-dns-names", []string{""}, "DNS names that should be present on certificates generated by the dynamic serving CA")
	fs.StringVar(&o.Kubeconfig, "kubeconfig", "", "optional path to the kubeconfig used to connect to the apiserver. If not specified, in-cluster-config will be used")

	tlsCipherPossibleValues := cliflag.TLSCipherPossibleValues()
	fs.StringSliceVar(&o.TLSCipherSuites, "tls-cipher-suites", o.TLSCipherSuites,
		"Comma-separated list of cipher suites for the server. "+
			"If omitted, the default Go cipher suites will be use.  "+
			"Possible values: "+strings.Join(tlsCipherPossibleValues, ","))
	tlsPossibleVersions := cliflag.TLSPossibleVersions()
	fs.StringVar(&o.MinTLSVersion, "tls-min-version", o.MinTLSVersion,
		"Minimum TLS version supported. "+
			"Possible values: "+strings.Join(tlsPossibleVersions, ", "))
}

func FileTLSSourceEnabled(o WebhookOptions) bool {
	if o.TLSCertFile != "" || o.TLSKeyFile != "" {
		return true
	}
	return false
}

func DynamicTLSSourceEnabled(o WebhookOptions) bool {
	if o.DynamicServingCASecretNamespace != "" || o.DynamicServingCASecretName != "" {
		return true
	}
	return false
}
