package notify

import (
	"context"
	"fmt"
	"strings"

	"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"
	"go.skia.org/infra/perf/go/chromeperf"
	"go.skia.org/infra/perf/go/clustering2"
	"go.skia.org/infra/perf/go/git/provider"
	"go.skia.org/infra/perf/go/stepfit"
	"go.skia.org/infra/perf/go/ui/frame"
)

// ChromeperfNotifier struct used to send regression data to chromeperf.
type ChromePerfNotifier struct {
	chromePerfClient chromeperf.AnomalyApiClient
}

// NewChromePerfNotifier returns a new ChromePerfNotifier instance.
func NewChromePerfNotifier(ctx context.Context, anomalyApiClient chromeperf.AnomalyApiClient) (*ChromePerfNotifier, error) {
	var err error
	if anomalyApiClient == nil {
		anomalyApiClient, err = chromeperf.NewAnomalyApiClient(ctx, nil, nil)
		if err != nil {
			return nil, err
		}
	}

	sklog.Info("Creating a new chromeperf notifier")

	return &ChromePerfNotifier{
		chromePerfClient: anomalyApiClient,
	}, nil
}

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

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

	anomalyIds := []string{}
	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", 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)
		response, err := n.chromePerfClient.ReportRegression(
			ctx,
			getTestPath(paramset),
			int32(previousCommit.CommitNumber),
			int32(commit.CommitNumber),
			"chromium",
			isRegressionImprovement(paramset, cl.StepFit.Status),
			paramset["bot"],
			true,
			medianBeforeAnomaly,
			medianAfterAnomaly)

		if err != nil {
			return "", err
		}
		anomalyIds = append(anomalyIds, response.AnomalyId)
	}

	return strings.Join(anomalyIds, ","), nil
}

// RegressionMissing implements notify.Notifier.
// Invoked when a previous regression is recovered.
func (n *ChromePerfNotifier) RegressionMissing(
	ctx context.Context,
	commit,
	previousCommit provider.Commit,
	alert *alerts.Alert,
	cl *clustering2.ClusterSummary,
	frame *frame.FrameResponse,
	threadingReference string) error {
	sklog.Info("Sending regression missing information to Chromeperf")
	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) {
			const errorFormat = "Invalid paramset %s for chromeperf"
			sklog.Debugf(errorFormat, paramset)
			return skerr.Fmt(errorFormat, 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)
		_, err = n.chromePerfClient.ReportRegression(
			ctx,
			getTestPath(paramset),
			int32(previousCommit.CommitNumber),
			int32(commit.CommitNumber),
			"chromium",
			isRegressionImprovement(paramset, cl.StepFit.Status),
			paramset["bot"],
			true,
			medianBeforeAnomaly,
			medianAfterAnomaly)
		if err != nil {
			return err
		}
	}

	return nil
}

// ExampleSend is for dummy data. Do nothing!
func (n *ChromePerfNotifier) ExampleSend(ctx context.Context, alert *alerts.Alert) error {
	sklog.Info("Doing example send on chromeperf notifier")
	return nil
}

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

// isParamSetValid returns true if the paramsets contains all the
// keys required by chromeperf api.
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
}

// isRegressionImprovement returns true if the metric has moved towards the improvement direction.
func isRegressionImprovement(paramset map[string]string, stepFitStatus stepfit.StepFitStatus) bool {
	if _, ok := paramset["improvement_direction"]; ok {
		improvementDirection := paramset["improvement_direction"]
		return improvementDirection == "down" && stepFitStatus == stepfit.LOW || improvementDirection == "up" && stepFitStatus == stepfit.HIGH
	}

	return false
}

// GetTestPath returns a test path based on the values found in the paramset.
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
}
