/*
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"
	"regexp"
	"strings"
	"time"

	"go.uber.org/multierr"
	"k8s.io/apimachinery/pkg/runtime"

	"github.com/apache/camel-k/deploy"
	"github.com/apache/camel-k/pkg/apis"
	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
	"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/watch"

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

	corev1 "k8s.io/api/core/v1"
	k8serrors "k8s.io/apimachinery/pkg/api/errors"
)

func newCmdInstall(rootCmdOptions *RootCmdOptions) *cobra.Command {
	impl := installCmdOptions{
		RootCmdOptions: rootCmdOptions,
	}
	cmd := cobra.Command{
		Use:     "install",
		Short:   "Install Camel K on a Kubernetes cluster",
		Long:    `Installs Camel K on a Kubernetes or OpenShift cluster.`,
		PreRunE: impl.validate,
		RunE:    impl.install,
	}

	cmd.Flags().BoolVarP(&impl.wait, "wait", "w", false, "Waits for the platform to be running")
	cmd.Flags().BoolVar(&impl.clusterSetupOnly, "cluster-setup", false, "Execute cluster-wide operations only (may require admin rights)")
	cmd.Flags().BoolVar(&impl.skipOperatorSetup, "skip-operator-setup", false, "Do not install the operator in the namespace (in case there's a global one)")
	cmd.Flags().BoolVar(&impl.skipClusterSetup, "skip-cluster-setup", false, "Skip the cluster-setup phase")
	cmd.Flags().BoolVar(&impl.exampleSetup, "example", false, "Install example integration")
	cmd.Flags().BoolVar(&impl.global, "global", false, "Configure the operator to watch all namespaces. No integration platform is created.")

	cmd.Flags().StringVarP(&impl.outputFormat, "output", "o", "", "Output format. One of: json|yaml")
	cmd.Flags().StringVar(&impl.registry.Organization, "organization", "", "A organization on the Docker registry that can be used to publish images")
	cmd.Flags().StringVar(&impl.registry.Address, "registry", "", "A Docker registry that can be used to publish images")
	cmd.Flags().StringVar(&impl.registry.Secret, "registry-secret", "", "A secret used to push/pull images to the Docker registry")
	cmd.Flags().BoolVar(&impl.registry.Insecure, "registry-insecure", false, "Configure to configure registry access in insecure mode or not")
	cmd.Flags().StringSliceVarP(&impl.properties, "property", "p", nil, "Add a camel property")
	cmd.Flags().StringVar(&impl.camelVersion, "camel-version", "", "Set the camel version")
	cmd.Flags().StringVar(&impl.runtimeVersion, "runtime-version", "", "Set the camel-k runtime version")
	cmd.Flags().StringVar(&impl.baseImage, "base-image", "", "Set the base image used to run integrations")
	cmd.Flags().StringVar(&impl.operatorImage, "operator-image", "", "Set the operator image used for the operator deployment")
	cmd.Flags().StringSliceVar(&impl.kits, "kit", nil, "Add an integration kit to build at startup")
	cmd.Flags().StringVar(&impl.buildStrategy, "build-strategy", "", "Set the build strategy")
	cmd.Flags().StringVar(&impl.buildTimeout, "build-timeout", "", "Set how long the build process can last")
	cmd.Flags().StringVar(&impl.traitProfile, "trait-profile", "", "The profile to use for traits")
	cmd.Flags().BoolVar(&impl.kanikoBuildCache, "kaniko-build-cache", true, "To enable or disable the Kaniko Cache in building phase")
	cmd.Flags().StringVar(&impl.httpProxySecret, "http-proxy-secret", "", "Configure the source of the secret holding HTTP proxy server details "+
		"(HTTP_PROXY|HTTPS_PROXY|NO_PROXY)")

	// maven settings
	cmd.Flags().StringVar(&impl.localRepository, "local-repository", "", "Location of the local maven repository")
	cmd.Flags().StringVar(&impl.mavenSettings, "maven-settings", "", "Configure the source of the maven settings (configmap|secret:name[/key])")
	cmd.Flags().StringSliceVar(&impl.mavenRepositories, "maven-repository", nil, "Add a maven repository")

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

	return &cmd
}

type installCmdOptions struct {
	*RootCmdOptions
	wait              bool
	clusterSetupOnly  bool
	skipOperatorSetup bool
	skipClusterSetup  bool
	exampleSetup      bool
	global            bool
	kanikoBuildCache  bool
	outputFormat      string
	camelVersion      string
	runtimeVersion    string
	baseImage         string
	operatorImage     string
	localRepository   string
	buildStrategy     string
	buildTimeout      string
	mavenRepositories []string
	mavenSettings     string
	properties        []string
	kits              []string
	registry          v1alpha1.IntegrationPlatformRegistrySpec
	traitProfile      string
	httpProxySecret   string
}

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

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

		err := install.SetupClusterWideResourcesOrCollect(o.Context, clientProvider, collection)
		if err != nil && k8serrors.IsForbidden(err) {
			fmt.Println("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.Println("Camel K cluster setup completed successfully")
		}
	} else {
		c, err := o.GetCmdClient()
		if err != nil {
			return err
		}

		namespace := o.Namespace

		if !o.skipOperatorSetup {
			cfg := install.OperatorConfiguration{
				CustomImage: o.operatorImage,
				Namespace:   namespace,
				Global:      o.global,
			}
			err = install.OperatorOrCollect(o.Context, c, cfg, collection)
			if err != nil {
				return err
			}
		} else {
			fmt.Println("Camel K operator installation skipped")
		}

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

		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.LocalRepository = o.localRepository
		}
		if o.camelVersion != "" {
			platform.Spec.Build.CamelVersion = o.camelVersion
		}
		if o.runtimeVersion != "" {
			platform.Spec.Build.RuntimeVersion = o.runtimeVersion
		}
		if o.baseImage != "" {
			platform.Spec.Build.BaseImage = o.baseImage
		}
		if o.buildStrategy != "" {
			switch s := o.buildStrategy; s {
			case v1alpha1.IntegrationPlatformBuildStrategyPod:
				platform.Spec.Build.BuildStrategy = v1alpha1.IntegrationPlatformBuildStrategyPod
			case v1alpha1.IntegrationPlatformBuildStrategyRoutine:
				platform.Spec.Build.BuildStrategy = v1alpha1.IntegrationPlatformBuildStrategyRoutine
			default:
				return fmt.Errorf("unknown build strategy: %s", s)
			}
		}
		if o.buildTimeout != "" {
			d, err := time.ParseDuration(o.buildTimeout)
			if err != nil {
				return err
			}

			platform.Spec.Build.Timeout.Duration = d
		}
		if o.traitProfile != "" {
			platform.Spec.Profile = v1alpha1.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
		}

		kanikoBuildCacheFlag := cobraCmd.Flags().Lookup("kaniko-build-cache")

		defaultKanikoBuildCache := true

		if kanikoBuildCacheFlag.Changed {
			platform.Spec.Build.KanikoBuildCache = &o.kanikoBuildCache
		} else {
			platform.Spec.Build.KanikoBuildCache = &defaultKanikoBuildCache
		}

		platform.Spec.Resources.Kits = o.kits

		// Do not create an integration platform in global mode as platforms are expected
		// to be created in other namespaces
		if !o.global {
			err = install.RuntimeObjectOrCollect(o.Context, c, namespace, collection, platform)
			if err != nil {
				return err
			}
		}

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

		if collection == nil {
			if o.wait {
				err = o.waitForPlatformReady(platform)
				if err != nil {
					return err
				}
			}

			if o.global {
				fmt.Println("Camel K installed in namespace", namespace, "(global mode)")
			} else {
				fmt.Println("Camel K installed in namespace", namespace)
			}
		}
	}

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

	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
}

func (o *installCmdOptions) waitForPlatformReady(platform *v1alpha1.IntegrationPlatform) error {
	handler := func(i *v1alpha1.IntegrationPlatform) bool {
		if i.Status.Phase != "" {
			fmt.Println("platform \""+platform.Name+"\" in phase", i.Status.Phase)

			if i.Status.Phase == v1alpha1.IntegrationPlatformPhaseReady {
				// TODO display some error info when available in the status
				return false
			}

			if i.Status.Phase == v1alpha1.IntegrationPlatformPhaseError {
				fmt.Println("platform installation failed")
				return false
			}
		}

		return true
	}

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

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
	}

	for _, kit := range o.kits {
		err := errorIfKitIsNotAvailable(schema, kit)
		result = multierr.Append(result, 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 := v1alpha1.TraitProfileByName(o.traitProfile)
		if tp == v1alpha1.TraitProfile("") {
			err := fmt.Errorf("unknown trait profile %s", o.traitProfile)
			result = multierr.Append(result, err)
		}
	}

	return result
}

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

func decodeMavenSettings(mavenSettings string) (v1alpha1.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 v1alpha1.ValueSource{
				ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
					LocalObjectReference: corev1.LocalObjectReference{
						Name: sub[1],
					},
					Key: key,
				},
			}, nil
		}
		if sub[0] == "secret" {
			return v1alpha1.ValueSource{
				SecretKeyRef: &corev1.SecretKeySelector{
					LocalObjectReference: corev1.LocalObjectReference{
						Name: sub[1],
					},
					Key: key,
				},
			}, nil
		}
	}

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