package notifier

import (
	"context"
	"fmt"

	"go.skia.org/infra/go/query"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/vec32"
	"go.skia.org/infra/perf/go/alerts"
	ag "go.skia.org/infra/perf/go/anomalygroup/utils"
	"go.skia.org/infra/perf/go/clustering2"
	"go.skia.org/infra/perf/go/git/provider"
	"go.skia.org/infra/perf/go/ui/frame"
)

// AnomalyGroupNotifier struct used to group regression and trigger group action.
type AnomalyGroupNotifier struct {
	grouper ag.AnomalyGrouper
}

// NewAnomalyGroupNotifier returns a new AnomalyGroupNotifier instance.
func NewAnomalyGroupNotifier(ctx context.Context, anomalygrouper ag.AnomalyGrouper) *AnomalyGroupNotifier {
	if anomalygrouper == nil {
		anomalygrouper = &ag.AnomalyGrouperImpl{}
	}

	sklog.Info("Creating a new anomaly group notifier")

	return &AnomalyGroupNotifier{
		grouper: anomalygrouper,
	}
}

// RegressionFound implements notify.Notifier.
// Invoked when a new regression is detected.
func (n *AnomalyGroupNotifier) RegressionFound(
	ctx context.Context,
	commit,
	previousCommit provider.Commit,
	alert *alerts.Alert,
	cl *clustering2.ClusterSummary,
	frame *frame.FrameResponse,
	regressionID string) (string, error) {

	sklog.Infof("[AG] %d traces in regression found information for alert %s", len(frame.DataFrame.TraceSet), alert.DisplayName)

	// Debug logs on b/357628141: why the same anomaly id is added to the group multiple times?
	if len(frame.DataFrame.TraceSet) > 1 {
		traceset_keys := make([]string, len(frame.DataFrame.TraceSet))
		i := 0
		for traceset_key := range frame.DataFrame.TraceSet {
			traceset_keys[i] = traceset_key
			i++
		}
		sklog.Debugf("[AG] More than one keys found in anomaly's traceset. Anomaly: %s. Keys: %s", regressionID, traceset_keys)
	}

	for key := range frame.DataFrame.TraceSet {
		paramset, err := query.ParseKey(key)
		if err != nil {
			return "", skerr.Wrapf(err, "Error parsing key %s", key)
		}

		if !isParamSetValid(paramset) {
			return "", skerr.Fmt("Invalid paramset %s for chromeperf data", paramset)
		}

		medianBeforeAnomaly, _, _, _ := vec32.TwoSidedStdDev(cl.Centroid[:cl.StepFit.TurningPoint])
		medianAfterAnomaly, _, _, _ := vec32.TwoSidedStdDev(cl.Centroid[cl.StepFit.TurningPoint:])
		sklog.Infof("Median Before: %f, Median After: %f", medianBeforeAnomaly, medianAfterAnomaly)

		testPath := getTestPath(paramset)

		_, err = n.grouper.ProcessRegressionInGroup(
			ctx,
			alert,
			regressionID,
			int64(previousCommit.CommitNumber),
			int64(commit.CommitNumber),
			testPath,
			paramset)
		if err != nil {
			return "", skerr.Wrapf(err, "error processing regression")
		}
	}

	return "", nil
}

// RegressionMissing implements notify.Notifier.
// Invoked when a previous regression is recovered.
func (n *AnomalyGroupNotifier) RegressionMissing(
	ctx context.Context,
	commit,
	previousCommit provider.Commit,
	alert *alerts.Alert,
	cl *clustering2.ClusterSummary,
	frame *frame.FrameResponse,
	threadingReference string) error {

	sklog.Info("No op function for AnomalyGroupNotifier.RegressionMissing")
	return nil
}

// ExampleSend is for dummy data. Do nothing!
func (n *AnomalyGroupNotifier) ExampleSend(ctx context.Context, alert *alerts.Alert) error {
	sklog.Info("No op function for AnomalyGroupNotifier.ExampleSend")
	return nil
}

// UpdateRegressionNotification implements Transport.
func (n *AnomalyGroupNotifier) UpdateNotification(ctx context.Context, commit, previousCommit provider.Commit, alert *alerts.Alert, cl *clustering2.ClusterSummary, frame *frame.FrameResponse, notificationId string) error {
	return nil
}

// GetTestPath returns a test path based on the values found in the paramset.
// TODO(wenbinzhang): using kvp in config to control which keys to expect
func getTestPath(paramset map[string]string) string {
	keys := []string{"bot", "benchmark", "test", "subtest_1", "subtest_2", "subtest_3"}
	testPath := paramset["master"]
	for _, key := range keys {
		val, ok := paramset[key]
		if ok {
			testPath = fmt.Sprintf("%s/%s", testPath, val)
		} else {
			break
		}
	}
	return testPath
}

// isParamSetValid returns true if the paramsets contains all the
// keys required by chromeperf api.
// TODO(wenbinzhang): using kvp in config to control which keys to expect
func isParamSetValid(paramset map[string]string) bool {
	requiredKeys := []string{"master", "bot", "benchmark", "test", "subtest_1"}
	for _, key := range requiredKeys {
		_, ok := paramset[key]
		if !ok {
			return false
		}
	}

	return true
}
