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

import (
	"fmt"
	"path"
	"strconv"
	"strings"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/intstr"

	monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1"

	"github.com/apache/camel-k/deploy"
	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
	"github.com/apache/camel-k/pkg/util"
)

// The Prometheus trait configures a Prometheus-compatible endpoint. It also exposes the integration with a `Service`
// and a `ServiceMonitor` resources, so that the endpoint can be scraped automatically, when using the Prometheus
// operator.
//
// The metrics exposed vary depending on the configured runtime. With Quarkus, the metrics are exposed
// using MicroProfile Metrics. While with the default runtime, they are exposed using the Prometheus JMX exporter.
//
// WARNING: The creation of the `ServiceMonitor` resource requires the https://github.com/coreos/prometheus-operator[Prometheus Operator]
// custom resource definition to be installed.
// You can set `service-monitor` to `false` for the Prometheus trait to work without the Prometheus operator.
//
// It's disabled by default.
//
// +camel-k:trait=prometheus
type prometheusTrait struct {
	BaseTrait `property:",squash"`
	// The Prometheus endpoint port (default `9779`, or `8080` with Quarkus).
	Port *int `property:"port"`
	// Whether a `ServiceMonitor` resource is created (default `true`).
	ServiceMonitor bool `property:"service-monitor"`
	// The `ServiceMonitor` resource labels, applicable when `service-monitor` is `true`.
	ServiceMonitorLabels string `property:"service-monitor-labels"`
	// To use a custom ConfigMap containing the Prometheus JMX exporter configuration (under the `content` ConfigMap key).
	// When this property is left empty (default), Camel K generates a standard Prometheus configuration for the integration.
	// It is not applicable when using Quarkus.
	ConfigMap string `property:"configmap"`
}

const (
	prometheusJmxExporterConfigFileName  = "prometheus-jmx-exporter.yaml"
	prometheusJmxExporterConfigMountPath = "/etc/prometheus"
	prometheusPortName                   = "prometheus"
)

func newPrometheusTrait() Trait {
	return &prometheusTrait{
		BaseTrait:      NewBaseTrait("prometheus", 1900),
		ServiceMonitor: true,
	}
}

func (t *prometheusTrait) Configure(e *Environment) (bool, error) {
	return t.Enabled != nil && *t.Enabled && e.IntegrationInPhase(
		v1.IntegrationPhaseInitialization,
		v1.IntegrationPhaseDeploying,
		v1.IntegrationPhaseRunning,
	), nil
}

func (t *prometheusTrait) Apply(e *Environment) (err error) {
	if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) {
		switch e.CamelCatalog.Runtime.Provider {
		case v1.RuntimeProviderQuarkus:
			// Add the Camel Quarkus MP Metrics extension
			util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, "mvn:org.apache.camel.quarkus/camel-quarkus-microprofile-metrics")
		case v1.RuntimeProviderMain:
			// Add the Camel management and Prometheus agent dependencies
			util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, "mvn:org.apache.camel/camel-management")
			// TODO: We may want to make the Prometheus version configurable
			util.StringSliceUniqueAdd(&e.Integration.Status.Dependencies, "mvn:io.prometheus.jmx/jmx_prometheus_javaagent:0.3.1")

			// Use the provided configuration or add the default Prometheus JMX exporter configuration
			configMapName := t.getJmxExporterConfigMapOrAdd(e)

			e.Integration.Status.AddOrReplaceGeneratedResources(v1.ResourceSpec{
				Type: v1.ResourceTypeData,
				DataSpec: v1.DataSpec{
					Name:       prometheusJmxExporterConfigFileName,
					ContentRef: configMapName,
				},
				MountPath: prometheusJmxExporterConfigMountPath,
			})
		}
		return nil
	}

	container := e.getIntegrationContainer()
	if container == nil {
		e.Integration.Status.SetCondition(
			v1.IntegrationConditionPrometheusAvailable,
			corev1.ConditionFalse,
			v1.IntegrationConditionContainerNotAvailableReason,
			"",
		)
		return nil
	}

	condition := v1.IntegrationCondition{
		Type:   v1.IntegrationConditionPrometheusAvailable,
		Status: corev1.ConditionTrue,
		Reason: v1.IntegrationConditionPrometheusAvailableReason,
	}

	var port int
	switch e.CamelCatalog.Runtime.Provider {
	case v1.RuntimeProviderQuarkus:
		port = 8080
	case v1.RuntimeProviderMain:
		port = 9779
		// Configure the Prometheus Java agent
		options := []string{strconv.Itoa(port), path.Join(prometheusJmxExporterConfigMountPath, prometheusJmxExporterConfigFileName)}
		container.Args = append(container.Args, "-javaagent:dependencies/io.prometheus.jmx.jmx_prometheus_javaagent-0.3.1.jar="+strings.Join(options, ":"))
	}

	if t.Port == nil {
		t.Port = &port
	}

	// Configure the Prometheus container port
	containerPort := t.getContainerPort()
	controller, err := e.DetermineControllerStrategy()
	if err != nil {
		return err
	}
	// Skip declaring the Prometheus port when Knative is enabled, as only one container port is supported
	if controller != ControllerStrategyKnativeService {
		container.Ports = append(container.Ports, *containerPort)
	}
	condition.Message = fmt.Sprintf("%s(%d)", container.Name, containerPort.ContainerPort)

	// Retrieve the service or create a new one if the service trait is enabled
	serviceEnabled := false
	service := e.Resources.GetServiceForIntegration(e.Integration)
	if service == nil {
		trait := e.Catalog.GetTrait(serviceTraitID)
		if serviceTrait, ok := trait.(*serviceTrait); ok {
			serviceEnabled = serviceTrait.isEnabled()
		}
		if serviceEnabled {
			// Add a new service if not already created
			service = getServiceFor(e)
			// Override the service name if none exists.
			// This is required for Knative Serving, that checks no standard eponymous service exist
			service.Name += "-prometheus"
			e.Resources.Add(service)
		}
	} else {
		serviceEnabled = true
	}

	// Add the service port and service monitor resource
	if serviceEnabled {
		servicePort := t.getServicePort()
		service.Spec.Ports = append(service.Spec.Ports, *servicePort)
		condition.Message = fmt.Sprintf("%s(%s/%d) -> ", service.Name, servicePort.Name, servicePort.Port) + condition.Message

		// Add the ServiceMonitor resource
		if t.ServiceMonitor {
			smt, err := t.getServiceMonitorFor(e)
			if err != nil {
				return err
			}
			e.Resources.Add(smt)
		}
	} else {
		condition.Status = corev1.ConditionFalse
		condition.Reason = v1.IntegrationConditionServiceNotAvailableReason
	}

	e.Integration.Status.SetConditions(condition)

	return nil
}

func (t *prometheusTrait) getContainerPort() *corev1.ContainerPort {
	containerPort := corev1.ContainerPort{
		ContainerPort: int32(*t.Port),
		Protocol:      corev1.ProtocolTCP,
	}
	return &containerPort
}

func (t *prometheusTrait) getServicePort() *corev1.ServicePort {
	servicePort := corev1.ServicePort{
		Name:     prometheusPortName,
		Port:     int32(*t.Port),
		Protocol: corev1.ProtocolTCP,
		// Avoid relying on named port, as Knative enforces specific values used for content negotiation
		TargetPort: intstr.FromInt(*t.Port),
	}
	return &servicePort
}

func (t *prometheusTrait) getServiceMonitorFor(e *Environment) (*monitoringv1.ServiceMonitor, error) {
	labels, err := parseCsvMap(&t.ServiceMonitorLabels)
	if err != nil {
		return nil, err
	}
	labels[v1.IntegrationLabel] = e.Integration.Name

	smt := monitoringv1.ServiceMonitor{
		TypeMeta: metav1.TypeMeta{
			Kind:       "ServiceMonitor",
			APIVersion: "monitoring.coreos.com/v1",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name:      e.Integration.Name,
			Namespace: e.Integration.Namespace,
			Labels:    labels,
		},
		Spec: monitoringv1.ServiceMonitorSpec{
			Selector: metav1.LabelSelector{
				MatchLabels: map[string]string{
					v1.IntegrationLabel: e.Integration.Name,
				},
			},
			Endpoints: []monitoringv1.Endpoint{
				{
					Port: prometheusPortName,
				},
			},
		},
	}
	return &smt, nil
}

func (t *prometheusTrait) getJmxExporterConfigMapOrAdd(e *Environment) string {
	if t.ConfigMap != "" {
		return t.ConfigMap
	}

	// Add a default config if not specified by the user
	defaultName := e.Integration.Name + "-prometheus"
	cm := corev1.ConfigMap{
		TypeMeta: metav1.TypeMeta{
			Kind:       "ConfigMap",
			APIVersion: "v1",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name:      defaultName,
			Namespace: e.Integration.Namespace,
			Labels: map[string]string{
				v1.IntegrationLabel: e.Integration.Name,
			},
		},
		Data: map[string]string{
			"content": deploy.ResourceAsString("/prometheus-jmx-exporter.yaml"),
		},
	}
	e.Resources.Add(&cm)
	return defaultName
}
