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

import (
	"fmt"
	"os"
	"regexp"
	"strings"
	"time"

	"go.uber.org/multierr"

	"github.com/pkg/errors"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"

	corev1 "k8s.io/api/core/v1"
	k8serrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"

	"github.com/apache/camel-k/deploy"
	"github.com/apache/camel-k/pkg/apis"
	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
	"github.com/apache/camel-k/pkg/client"
	"github.com/apache/camel-k/pkg/install"
	"github.com/apache/camel-k/pkg/util/kubernetes"
	"github.com/apache/camel-k/pkg/util/olm"
	"github.com/apache/camel-k/pkg/util/registry"
	"github.com/apache/camel-k/pkg/util/watch"
)

func newCmdInstall(rootCmdOptions *RootCmdOptions) (*cobra.Command, *installCmdOptions) {
	options := installCmdOptions{
		RootCmdOptions: rootCmdOptions,
	}
	cmd := cobra.Command{
		Use:     "install",
		Short:   "Install Camel K on a Kubernetes cluster",
		Long:    `Install Camel K on a Kubernetes or OpenShift cluster.`,
		PreRunE: options.decode,
		RunE: func(cmd *cobra.Command, args []string) error {
			if err := options.validate(cmd, args); err != nil {
				return err
			}
			if err := options.install(cmd, args); err != nil {
				if k8serrors.IsAlreadyExists(err) {
					return errors.Wrap(err, "Camel K seems already installed (use the --force option to overwrite existing resources)")
				}
				return err
			}
			return nil
		},
		PostRunE: options.postRun,
	}

	cmd.Flags().BoolP("wait", "w", false, "Wait for the platform to be running")
	cmd.Flags().Bool("cluster-setup", false, "Execute cluster-wide operations only (may require admin rights)")
	cmd.Flags().String("cluster-type", "", "Set explicitly the cluster type to Kubernetes or OpenShift")
	cmd.Flags().Bool("skip-operator-setup", false, "Do not install the operator in the namespace (in case there's a global one)")
	cmd.Flags().Bool("skip-cluster-setup", false, "Skip the cluster-setup phase")
	cmd.Flags().Bool("example", false, "Install example integration")
	cmd.Flags().Bool("global", false, "Configure the operator to watch all namespaces. No integration platform is created.")
	cmd.Flags().Bool("force", false, "Force replacement of configuration resources when already present.")

	cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml")
	cmd.Flags().String("organization", "", "A organization on the Docker registry that can be used to publish images")
	cmd.Flags().String("registry", "", "A Docker registry that can be used to publish images")
	cmd.Flags().String("registry-secret", "", "A secret used to push/pull images to the Docker registry")
	cmd.Flags().Bool("registry-insecure", false, "Configure to configure registry access in insecure mode or not")
	cmd.Flags().String("registry-auth-file", "", "A docker registry configuration file containing authorization tokens for pushing and pulling images")
	cmd.Flags().String("registry-auth-server", "", "The docker registry authentication server")
	cmd.Flags().String("registry-auth-username", "", "The docker registry authentication username")
	cmd.Flags().String("registry-auth-password", "", "The docker registry authentication password")
	cmd.Flags().StringArrayP("property", "p", nil, "Add a camel property")
	cmd.Flags().String("camel-version", "", "Set the camel version")
	cmd.Flags().String("runtime-version", "", "Set the camel-k runtime version")
	cmd.Flags().String("base-image", "", "Set the base Image used to run integrations")
	cmd.Flags().String("operator-image", "", "Set the operator Image used for the operator deployment")
	cmd.Flags().String("operator-image-pull-policy", "", "Set the operator ImagePullPolicy used for the operator deployment")
	cmd.Flags().String("build-strategy", "", "Set the build strategy")
	cmd.Flags().String("build-publish-strategy", "", "Set the build publish strategy")
	cmd.Flags().String("build-timeout", "", "Set how long the build process can last")
	cmd.Flags().String("trait-profile", "", "The profile to use for traits")
	cmd.Flags().Bool("kaniko-build-cache", false, "To enable or disable the Kaniko cache")
	cmd.Flags().String("http-proxy-secret", "", "Configure the source of the secret holding HTTP proxy server details "+
		"(HTTP_PROXY|HTTPS_PROXY|NO_PROXY)")

	// OLM
	cmd.Flags().Bool("olm", true, "Try to install everything via OLM (Operator Lifecycle Manager) if available")
	cmd.Flags().String("olm-operator-name", olm.DefaultOperatorName, "Name of the Camel K operator in the OLM source or marketplace")
	cmd.Flags().String("olm-package", olm.DefaultPackage, "Name of the Camel K package in the OLM source or marketplace")
	cmd.Flags().String("olm-channel", olm.DefaultChannel, "Name of the Camel K channel in the OLM source or marketplace")
	cmd.Flags().String("olm-source", olm.DefaultSource, "Name of the OLM source providing the Camel K package (defaults to the standard Operator Hub source)")
	cmd.Flags().String("olm-source-namespace", olm.DefaultSourceNamespace, "Namespace where the OLM source is available")
	cmd.Flags().String("olm-starting-csv", olm.DefaultStartingCSV, "Allow to install a specific version from the operator source instead of latest available "+
		"from the channel")
	cmd.Flags().String("olm-global-namespace", olm.DefaultGlobalNamespace, "A namespace containing an OperatorGroup that defines global scope for the "+
		"operator (used in combination with the --global flag)")

	// Maven settings
	cmd.Flags().String("local-repository", "", "Location of the local maven repository")
	cmd.Flags().String("maven-settings", "", "Configure the source of the maven settings (configmap|secret:name[/key])")
	cmd.Flags().StringArray("maven-repository", nil, "Add a maven repository")

	// health
	cmd.Flags().Int("health-port", 8081, "The port of the health endpoint")

	// monitoring
	cmd.Flags().Bool("monitoring", false, "To enable or disable the operator monitoring")
	cmd.Flags().Int("monitoring-port", 8080, "The port of the metrics endpoint")

	// save
	cmd.Flags().Bool("save", false, "Save the install parameters into the default kamel configuration file (kamel-config.yaml)")

	// completion support
	configureBashAnnotationForFlag(
		&cmd,
		"context",
		map[string][]string{
			cobra.BashCompCustom: {"__kamel_kubectl_get_known_integrationcontexts"},
		},
	)

	return &cmd, &options
}

type installCmdOptions struct {
	*RootCmdOptions
	Wait                    bool     `mapstructure:"wait"`
	ClusterSetupOnly        bool     `mapstructure:"cluster-setup"`
	SkipOperatorSetup       bool     `mapstructure:"skip-operator-setup"`
	SkipClusterSetup        bool     `mapstructure:"skip-cluster-setup"`
	ExampleSetup            bool     `mapstructure:"example"`
	Global                  bool     `mapstructure:"global"`
	KanikoBuildCache        bool     `mapstructure:"kaniko-build-cache"`
	Save                    bool     `mapstructure:"save" kamel:"omitsave"`
	Force                   bool     `mapstructure:"force"`
	Olm                     bool     `mapstructure:"olm"`
	ClusterType             string   `mapstructure:"cluster-type"`
	OutputFormat            string   `mapstructure:"output"`
	RuntimeVersion          string   `mapstructure:"runtime-version"`
	BaseImage               string   `mapstructure:"base-image"`
	OperatorImage           string   `mapstructure:"operator-image"`
	OperatorImagePullPolicy string   `mapstructure:"operator-image-pull-policy"`
	LocalRepository         string   `mapstructure:"local-repository"`
	BuildStrategy           string   `mapstructure:"build-strategy"`
	BuildPublishStrategy    string   `mapstructure:"build-publish-strategy"`
	BuildTimeout            string   `mapstructure:"build-timeout"`
	MavenRepositories       []string `mapstructure:"maven-repositories"`
	MavenSettings           string   `mapstructure:"maven-settings"`
	HealthPort              int32    `mapstructure:"health-port"`
	Monitoring              bool     `mapstructure:"monitoring"`
	MonitoringPort          int32    `mapstructure:"monitoring-port"`
	Properties              []string `mapstructure:"properties"`
	TraitProfile            string   `mapstructure:"trait-profile"`
	HTTPProxySecret         string   `mapstructure:"http-proxy-secret"`

	registry         v1.IntegrationPlatformRegistrySpec
	registryAuth     registry.Auth
	RegistryAuthFile string `mapstructure:"registry-auth-file"`

	olmOptions olm.Options
}

// nolint: gocyclo
func (o *installCmdOptions) install(cobraCmd *cobra.Command, _ []string) error {
	var collection *kubernetes.Collection
	if o.OutputFormat != "" {
		collection = kubernetes.NewCollection()
	}

	// Let's use a client provider during cluster installation, to eliminate the problem of CRD object caching
	clientProvider := client.Provider{Get: o.NewCmdClient}

	installViaOLM := false
	if o.Olm {
		var err error
		var olmClient client.Client
		if olmClient, err = clientProvider.Get(); err != nil {
			return err
		}
		var olmAvailable bool
		if olmAvailable, err = olm.IsAPIAvailable(o.Context, olmClient, o.Namespace); err != nil {
			return errors.Wrap(err, "error while checking OLM availability. Run with '--olm=false' to skip this check")
		}

		if olmAvailable {
			if installViaOLM, err = olm.HasPermissionToInstall(o.Context, olmClient, o.Namespace, o.Global, o.olmOptions); err != nil {
				return errors.Wrap(err, "error while checking permissions to install operator via OLM. Run with '--olm=false' to skip this check")
			}
			if !installViaOLM {
				fmt.Fprintln(cobraCmd.OutOrStdout(), "OLM is available but current user has not enough permissions to create the operator. "+
					"You can either ask your administrator to provide permissions (preferred) or run the install command with the `--olm=false` flag.")
				os.Exit(1)
			}
		}

		if installViaOLM {
			fmt.Fprintln(cobraCmd.OutOrStdout(), "OLM is available in the cluster")
			var installed bool
			if installed, err = olm.Install(o.Context, olmClient, o.Namespace, o.Global, o.olmOptions, collection); err != nil {
				return err
			}
			if !installed {
				fmt.Fprintln(cobraCmd.OutOrStdout(), "OLM resources are already available: skipping installation")
			}

			if err = install.WaitForAllCRDInstallation(o.Context, clientProvider, 90*time.Second); err != nil {
				return err
			}
		}
	}

	if !o.SkipClusterSetup && !installViaOLM {
		err := install.SetupClusterWideResourcesOrCollect(o.Context, clientProvider, collection)
		if err != nil && k8serrors.IsForbidden(err) {
			fmt.Fprintln(cobraCmd.OutOrStdout(), "Current user is not authorized to create cluster-wide objects like custom resource definitions or cluster roles: ", err)

			meg := `please login as cluster-admin and execute "kamel install --cluster-setup" to install cluster-wide resources (one-time operation)`
			return errors.New(meg)
		} else if err != nil {
			return err
		}
	}

	if o.ClusterSetupOnly {
		if collection == nil {
			fmt.Fprintln(cobraCmd.OutOrStdout(), "Camel K cluster setup completed successfully")
		}
	} else {
		c, err := o.GetCmdClient()
		if err != nil {
			return err
		}

		namespace := o.Namespace

		if !o.SkipOperatorSetup && !installViaOLM {
			cfg := install.OperatorConfiguration{
				CustomImage:           o.OperatorImage,
				CustomImagePullPolicy: o.OperatorImagePullPolicy,
				Namespace:             namespace,
				Global:                o.Global,
				ClusterType:           o.ClusterType,
				Health: install.OperatorHealthConfiguration{
					Port: o.HealthPort,
				},
				Monitoring: install.OperatorMonitoringConfiguration{
					Enabled: o.Monitoring,
					Port:    o.MonitoringPort,
				},
			}
			err = install.OperatorOrCollect(o.Context, c, cfg, collection, o.Force)
			if err != nil {
				return err
			}
		} else if o.SkipOperatorSetup {
			fmt.Fprintln(cobraCmd.OutOrStdout(), "Camel K operator installation skipped")
		}

		generatedSecretName := ""
		if o.registryAuth.IsSet() {
			regData := o.registryAuth
			regData.Registry = o.registry.Address
			generatedSecretName, err = install.RegistrySecretOrCollect(o.Context, c, namespace, regData, collection, o.Force)
			if err != nil {
				return err
			}
		} else if o.RegistryAuthFile != "" {
			generatedSecretName, err = install.RegistrySecretFromFileOrCollect(o.Context, c, namespace, o.RegistryAuthFile, collection, o.Force)
			if err != nil {
				return err
			}
		}

		platform, err := install.PlatformOrCollect(o.Context, c, o.ClusterType, namespace, o.registry, collection)
		if err != nil {
			return err
		}

		if generatedSecretName != "" {
			platform.Spec.Build.Registry.Secret = generatedSecretName
		}

		if len(o.Properties) > 0 {
			platform.Spec.Build.Properties = make(map[string]string)

			for _, property := range o.Properties {
				kv := strings.Split(property, "=")

				if len(kv) == 2 {
					platform.Spec.Build.Properties[kv[0]] = kv[1]
				}
			}
		}
		if o.LocalRepository != "" {
			platform.Spec.Build.Maven.LocalRepository = o.LocalRepository
		}
		if o.RuntimeVersion != "" {
			platform.Spec.Build.RuntimeVersion = o.RuntimeVersion
		}
		if o.BaseImage != "" {
			platform.Spec.Build.BaseImage = o.BaseImage
		}
		if o.BuildStrategy != "" {
			platform.Spec.Build.BuildStrategy = v1.IntegrationPlatformBuildStrategy(o.BuildStrategy)
		}
		if o.BuildPublishStrategy != "" {
			platform.Spec.Build.PublishStrategy = v1.IntegrationPlatformBuildPublishStrategy(o.BuildPublishStrategy)
		}
		if o.BuildTimeout != "" {
			d, err := time.ParseDuration(o.BuildTimeout)
			if err != nil {
				return err
			}

			platform.Spec.Build.Timeout = &metav1.Duration{
				Duration: d,
			}
		}
		if o.TraitProfile != "" {
			platform.Spec.Profile = v1.TraitProfileByName(o.TraitProfile)
		}

		if len(o.MavenRepositories) > 0 {
			for _, r := range o.MavenRepositories {
				platform.AddConfiguration("repository", r)
			}
		}

		if o.MavenSettings != "" {
			mavenSettings, err := decodeMavenSettings(o.MavenSettings)
			if err != nil {
				return err
			}
			platform.Spec.Build.Maven.Settings = mavenSettings
		}

		if o.HTTPProxySecret != "" {
			platform.Spec.Build.HTTPProxySecret = o.HTTPProxySecret
		}

		if o.ClusterType != "" {
			for _, c := range v1.AllIntegrationPlatformClusters {
				if strings.EqualFold(string(c), o.ClusterType) {
					platform.Spec.Cluster = c
				}
			}
		}

		kanikoBuildCacheFlag := cobraCmd.Flags().Lookup("kaniko-build-cache")
		if kanikoBuildCacheFlag.Changed {
			platform.Spec.Build.KanikoBuildCache = &o.KanikoBuildCache
		}

		// Do not create an integration platform in global mode as platforms are expected
		// to be created in other namespaces.
		// In OLM mode, the operator is installed in an external namespace, so it's ok to install the platform locally.
		if !o.Global || installViaOLM {
			err = install.RuntimeObjectOrCollect(o.Context, c, namespace, collection, o.Force, platform)
			if err != nil {
				return err
			}
		}

		if o.ExampleSetup {
			err = install.ExampleOrCollect(o.Context, c, namespace, collection, o.Force)
			if err != nil {
				return err
			}
		}

		if collection == nil {
			if o.Wait {
				err = o.waitForPlatformReady(cobraCmd, platform)
				if err != nil {
					return err
				}
			}

			strategy := ""
			if installViaOLM {
				strategy = "via OLM subscription"
			}
			if o.Global {
				fmt.Println("Camel K installed in namespace", namespace, strategy, "(global mode)")
			} else {
				fmt.Println("Camel K installed in namespace", namespace, strategy)
			}
		}
	}

	if collection != nil {
		return o.printOutput(collection)
	}

	return nil
}

func (o *installCmdOptions) postRun(cmd *cobra.Command, _ []string) error {
	if o.Save {
		cfg, err := LoadConfiguration()
		if err != nil {
			return err
		}

		cfg.Update(cmd, pathToRoot(cmd), o, true)

		return cfg.Save()
	}

	return nil
}

func (o *installCmdOptions) printOutput(collection *kubernetes.Collection) error {
	lst := collection.AsKubernetesList()
	switch o.OutputFormat {
	case "yaml":
		data, err := kubernetes.ToYAML(lst)
		if err != nil {
			return err
		}
		fmt.Print(string(data))
	case "json":
		data, err := kubernetes.ToJSON(lst)
		if err != nil {
			return err
		}
		fmt.Print(string(data))
	default:
		return errors.New("unknown output format: " + o.OutputFormat)
	}
	return nil
}

// nolint:errcheck
func (o *installCmdOptions) waitForPlatformReady(cmd *cobra.Command, platform *v1.IntegrationPlatform) error {
	handler := func(i *v1.IntegrationPlatform) bool {
		if i.Status.Phase == v1.IntegrationPlatformPhaseReady || i.Status.Phase == v1.IntegrationPlatformPhaseError {
			return false
		}

		return true
	}

	go watch.HandleIntegrationPlatformEvents(o.Context, platform, func(event *corev1.Event) bool {
		fmt.Fprintln(cmd.OutOrStdout(), event.Message)
		return true
	})

	return watch.HandlePlatformStateChanges(o.Context, platform, handler)
}

func (o *installCmdOptions) decode(cmd *cobra.Command, _ []string) error {
	path := pathToRoot(cmd)
	if err := decodeKey(o, path); err != nil {
		return err
	}

	o.registry.Address = viper.GetString(path + ".registry")
	o.registry.Organization = viper.GetString(path + ".organization")
	o.registry.Secret = viper.GetString(path + ".registry-secret")
	o.registry.Insecure = viper.GetBool(path + ".registry-insecure")
	o.registryAuth.Username = viper.GetString(path + ".registry-auth-username")
	o.registryAuth.Password = viper.GetString(path + ".registry-auth-password")
	o.registryAuth.Server = viper.GetString(path + ".registry-auth-server")

	o.olmOptions.OperatorName = viper.GetString(path + ".olm-operator-name")
	o.olmOptions.Package = viper.GetString(path + ".olm-package")
	o.olmOptions.Channel = viper.GetString(path + ".olm-channel")
	o.olmOptions.Source = viper.GetString(path + ".olm-source")
	o.olmOptions.SourceNamespace = viper.GetString(path + ".olm-source-namespace")
	o.olmOptions.StartingCSV = viper.GetString(path + ".olm-starting-csv")
	o.olmOptions.GlobalNamespace = viper.GetString(path + ".olm-global-namespace")

	return nil
}

func (o *installCmdOptions) validate(_ *cobra.Command, _ []string) error {
	var result error

	// Let's register only our own APIs
	schema := runtime.NewScheme()
	if err := apis.AddToScheme(schema); err != nil {
		return err
	}

	if len(o.MavenRepositories) > 0 && o.MavenSettings != "" {
		err := fmt.Errorf("incompatible options combinations: you cannot set both mavenRepository and mavenSettings")
		result = multierr.Append(result, err)
	}

	if o.TraitProfile != "" {
		tp := v1.TraitProfileByName(o.TraitProfile)
		if tp == v1.TraitProfile("") {
			err := fmt.Errorf("unknown trait profile %s", o.TraitProfile)
			result = multierr.Append(result, err)
		}
	}

	if o.registry.Secret != "" && (o.registryAuth.IsSet() || o.RegistryAuthFile != "") {
		err := fmt.Errorf("incompatible options combinations: you cannot set both registry-secret and registry-auth-[*] settings")
		result = multierr.Append(result, err)
	}

	if o.registryAuth.IsSet() && o.RegistryAuthFile != "" {
		err := fmt.Errorf("incompatible options combinations: you cannot set registry-auth-file with other registry-auth-[*] settings")
		result = multierr.Append(result, err)
	}

	if o.RegistryAuthFile != "" {
		nfo, err := os.Stat(o.RegistryAuthFile)
		if err != nil {
			result = multierr.Append(result, err)
		} else if nfo.IsDir() {
			result = multierr.Append(result, errors.Wrapf(err, "registry file cannot be a directory: %s", o.RegistryAuthFile))
		}
	}

	if o.BuildStrategy != "" {
		found := false
		for _, s := range v1.IntegrationPlatformBuildStrategies {
			if string(s) == o.BuildStrategy {
				found = true
				break
			}
		}
		if !found {
			var strategies []string
			for _, s := range v1.IntegrationPlatformBuildStrategies {
				strategies = append(strategies, string(s))
			}
			return fmt.Errorf("unknown build strategy: %s. One of [%s] is expected", o.BuildStrategy, strings.Join(strategies, ", "))
		}
	}

	if o.BuildPublishStrategy != "" {
		found := false
		for _, s := range v1.IntegrationPlatformBuildPublishStrategies {
			if string(s) == o.BuildPublishStrategy {
				found = true
				break
			}
		}
		if !found {
			var strategies []string
			for _, s := range v1.IntegrationPlatformBuildPublishStrategies {
				strategies = append(strategies, string(s))
			}
			return fmt.Errorf("unknown build publish strategy: %s. One of [%s] is expected", o.BuildPublishStrategy, strings.Join(strategies, ", "))
		}
	}

	return result
}

func errorIfKitIsNotAvailable(schema *runtime.Scheme, kit string) error {
	for _, name := range deploy.Resources("/") {
		resourceData := deploy.ResourceAsString(name)
		resource, err := kubernetes.LoadResourceFromYaml(schema, resourceData)
		if err != nil {
			// Not one of our registered schemas
			continue
		}
		kind := resource.GetObjectKind().GroupVersionKind()
		if kind.Kind != "IntegrationKit" {
			continue
		}
		integrationKit := resource.(*v1.IntegrationKit)
		if integrationKit.Name == kit {
			return nil
		}
	}
	return errors.Errorf("Unknown kit '%s'", kit)
}

func decodeMavenSettings(mavenSettings string) (v1.ValueSource, error) {
	sub := make([]string, 0)
	rex := regexp.MustCompile(`^(configmap|secret):([a-zA-Z0-9][a-zA-Z0-9-]*)(/([a-zA-Z0-9].*))?$`)
	hits := rex.FindAllStringSubmatch(mavenSettings, -1)

	for _, hit := range hits {
		if len(hit) > 1 {
			sub = append(sub, hit[1:]...)
		}
	}

	if len(sub) >= 2 {
		key := "settings.xml"

		if len(sub) == 4 {
			key = sub[3]
		}

		if sub[0] == "configmap" {
			return v1.ValueSource{
				ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
					LocalObjectReference: corev1.LocalObjectReference{
						Name: sub[1],
					},
					Key: key,
				},
			}, nil
		}
		if sub[0] == "secret" {
			return v1.ValueSource{
				SecretKeyRef: &corev1.SecretKeySelector{
					LocalObjectReference: corev1.LocalObjectReference{
						Name: sub[1],
					},
					Key: key,
				},
			}, nil
		}
	}

	return v1.ValueSource{}, fmt.Errorf("illegal maven setting definition, syntax: configmap|secret:resource-name[/settings path]")
}
