package kubepersistentvolumefillingup

import (
	"jirasop/model"
	"jirasop/pkg/infra/cliniccli"
	"jirasop/pkg/infra/config"
	"jirasop/pkg/infra/log"
	"strconv"

	"github.com/go-logr/logr"
)

type BigCompactionHandler struct {
	logger    logr.Logger
	clinicCli *cliniccli.ClinicClient
	config    []config.AlertReasonParam
}

func NewBigCompactionHandler(logconf config.LogConfig,
	config []config.AlertReasonParam,
	clinicCli *cliniccli.ClinicClient) *BigCompactionHandler {
	logr := log.Logger.WithName("BigCompaction")
	return &BigCompactionHandler{logger: logr, clinicCli: clinicCli, config: config}
}

func (bc *BigCompactionHandler) AnalyzeReason(issue *model.JiraWebhookEvent) (*model.AnalyzeReason, error) {
	judge := false
	issueStartAt := issue.Timestamp / 1000
	clusterID := issue.Issue.Fields.Unknowns["customfield_10616"].(string)
	tenantID := issue.Issue.Fields.Unknowns["customfield_10615"].(string)

	description := ``
	if clusterID != `` && tenantID != `` {

		// compaction reason.
		metricCompactionReason := bc.config[0]["metric"].(string)
		stepCompactionReason := strconv.Itoa(bc.config[0]["step"].(int))
		periodCompactionReason := bc.config[0]["period"].(int)
		start := issueStartAt - int64(periodCompactionReason)*60
		end := issueStartAt
		metrics, err := bc.clinicCli.GetOneMetricRequest(metricCompactionReason, clusterID, tenantID, start, end, stepCompactionReason+`m`)
		if err != nil {
			bc.logger.Error(err, "fail to get metrics")
			return nil, err
		}
		var biggest float64
		var reason string
		for i, v := range metrics.Result {
			val := v.Values
			tsValStr := val[0][1].(string)
			tsVal, _ := strconv.ParseFloat(tsValStr, 64)
			if i == 0 {
				biggest = tsVal
				reason = v.Metric.Reason
				continue
			}
			if len(val) > 0 && tsVal > biggest {
				biggest = tsVal
				reason = v.Metric.Reason
			}
		}
		description += `The most common compaction reason is *` + reason + `*.
`

		// compaction pending bytes.
		metricCompactionPending := bc.config[0]["metric"].(string)
		metrics, err = bc.clinicCli.GetOneMetricRequest(metricCompactionPending, clusterID, tenantID, start, end, stepCompactionReason+`m`)
		if err != nil {
			bc.logger.Error(err, "fail to get metrics")
			return nil, err
		}
		var pendingBytes float64
		for _, v := range metrics.Result {
			val := v.Values
			tsValStr := val[0][1].(string)
			tsVal, _ := strconv.ParseFloat(tsValStr, 64)
			pendingBytes = tsVal
		}
		if pendingBytes/1024/1024/1024 >= 192 {
			judge = true
		}
		description += `The total compaction pending bytes is *` + strconv.FormatFloat(pendingBytes/1024/1024, 'f', 2, 64) + `MB*.
`

		return &model.AnalyzeReason{Name: "BigCompactionJob", Is: judge, Description: description}, nil
	}
	return &model.AnalyzeReason{Name: "BigCompactionJob", Is: true, Description: "The tenant id or cluster id does not exist"}, nil
}
