/*
 * Copyright (c) 2026 Huawei Technologies Co., Ltd.
 * openFuyao is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

package analyzer

import (
	"encoding/json"

	"github.com/prometheus/client_golang/prometheus"
	ctrlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
)

var (
	nodeInterferenceLevel = prometheus.NewGaugeVec(prometheus.GaugeOpts{
		Name: "mco_node_interference_level",
		Help: "Analyzer calculated node interference level after smoothing.",
	}, []string{"node"})
	reportGenerationDuration = prometheus.NewHistogram(prometheus.HistogramOpts{
		Name:    "mco_analyzer_report_generation_duration_seconds",
		Help:    "Duration of analyzer report generation.",
		Buckets: prometheus.DefBuckets,
	})
	grpcRequestsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
		Name: "mco_analyzer_grpc_requests_total",
		Help: "Total analyzer gRPC requests.",
	}, []string{"method", "status"})
	collectorSamplesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
		Name: "mco_analyzer_collector_samples_total",
		Help: "Total collector samples accepted by analyzer.",
	}, []string{"node"})
	invalidMetricValuesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
		Name: "mco_analyzer_invalid_metric_values_total",
		Help: "Total invalid metric values sanitized by analyzer.",
	}, []string{"node", "metric", "reason"})
	crUpdateTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
		Name: "mco_analyzer_cr_updates_total",
		Help: "Total CR update attempts.",
	}, []string{"status"})
	crLastSuccessTimestamp = prometheus.NewGauge(prometheus.GaugeOpts{
		Name: "mco_analyzer_cr_last_success_timestamp_seconds",
		Help: "Unix timestamp of the last successful CR status update.",
	})
	ruleReloadTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
		Name: "mco_analyzer_rule_reload_total",
		Help: "Total detection rule reload attempts.",
	}, []string{"status"})
	ruleConfigInfo = prometheus.NewGaugeVec(prometheus.GaugeOpts{
		Name: "mco_analyzer_rule_config_info",
		Help: "Information about the currently loaded detection rule config.",
	}, []string{"hash", "path"})
	ruleLastReloadTimestamp = prometheus.NewGauge(prometheus.GaugeOpts{
		Name: "mco_analyzer_rule_last_reload_timestamp_seconds",
		Help: "Unix timestamp of the last successful detection rule reload.",
	})
)

func RegisterMetrics() {
	ctrlmetrics.Registry.MustRegister(nodeInterferenceLevel)
	ctrlmetrics.Registry.MustRegister(reportGenerationDuration)
	ctrlmetrics.Registry.MustRegister(grpcRequestsTotal)
	ctrlmetrics.Registry.MustRegister(collectorSamplesTotal)
	ctrlmetrics.Registry.MustRegister(invalidMetricValuesTotal)
	ctrlmetrics.Registry.MustRegister(crUpdateTotal)
	ctrlmetrics.Registry.MustRegister(crLastSuccessTimestamp)
	ctrlmetrics.Registry.MustRegister(ruleReloadTotal)
	ctrlmetrics.Registry.MustRegister(ruleConfigInfo)
	ctrlmetrics.Registry.MustRegister(ruleLastReloadTimestamp)
}

func mustJSON(value interface{}) []byte {
	data, err := json.Marshal(value)
	if err != nil {
		panic(err)
	}
	return data
}