package analyzer

import (
	"context"
	"fmt"
	"sort"
	"strings"
	"sync"

	"go.opencensus.io/trace"

	stat "github.com/aclements/go-moremath/stats"
	"github.com/bazelbuild/remote-apis-sdks/go/pkg/digest"
	"github.com/golang/protobuf/proto"
	"github.com/pkg/errors"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
	"golang.org/x/sync/errgroup"

	apipb "go.chromium.org/luci/swarming/proto/api_v2"
	"go.skia.org/infra/cabe/go/backends"
	cpb "go.skia.org/infra/cabe/go/proto"
	cabe_stats "go.skia.org/infra/cabe/go/stats"
	"go.skia.org/infra/perf/go/perfresults"
)

const maxReadCASPoolWorkers = 100

// Options configure one or more fields of an Analyzer instance.
type Options func(*Analyzer)

// WithCASResultReader configures an Analyzer instance to use the given CASResultReader.
func WithCASResultReader(r backends.CASResultReader) Options {
	return func(e *Analyzer) {
		e.readCAS = r
	}
}

// WithTaskResultsReader configures an Analyzer instance to use the given TaskResultsReader.
func WithSwarmingTaskReader(r backends.SwarmingTaskReader) Options {
	return func(e *Analyzer) {
		e.readSwarmingTasks = r
	}
}

// WithExperimentSpec configures an Analyzer instance to use the given ExperimentSpec.
func WithExperimentSpec(s *cpb.ExperimentSpec) Options {
	return func(e *Analyzer) {
		e.experimentSpec = s
	}
}

// New returns a new instance of Analyzer. Set either pinpointJobID, or controlDigests and treatmentDigests.
func New(pinpointJobID string, opts ...Options) *Analyzer {
	ret := &Analyzer{
		pinpointJobID: pinpointJobID,
		diagnostics:   newDiagnostics(),
	}
	for _, opt := range opts {
		opt(ret)
	}
	return ret
}

// Analyzer encapsulates the state of an Analyzer process execution. Its lifecycle follows a request
// to process all of the output of an A/B benchmark experiment run.
// Users of Analyzer must instantiate and attach the necessary service dependencies.
type Analyzer struct {
	pinpointJobID     string
	readCAS           backends.CASResultReader
	readSwarmingTasks backends.SwarmingTaskReader

	experimentSpec *cpb.ExperimentSpec
	diagnostics    *Diagnostics

	results []Results
}

func (a *Analyzer) Diagnostics() *Diagnostics {
	return a.diagnostics
}

// Results encapsulates a response from the Go statistical package after it has processed
// swarming task data and verified the experimental setup is valid for analysis.
type Results struct {
	// Benchmark is the name of a perf benchmark suite, such as Speedometer2 or JetStream
	Benchmark string
	// Workload is the name of a benchmark-specific workload, such as TodoMVC-ReactJS
	WorkLoad string
	// BuildConfig is the name of a build configuration, e.g. "Mac arm Builder Perf PGO"
	BuildConfig string
	// RunConfig is the name of a run configuration, e.g. "Macmini9,1_arm64-64-Apple_M1_16384_1_4744421.0"
	RunConfig string
	// Statistics summarizes the difference between the treatment and control arms for the given
	// Benchmark and Workload on the hardware described by RunConfig, using the binary built using
	// the given BuildConfig.
	Statistics *cabe_stats.BerfWilcoxonSignedRankedTestResult
}

// AnalysisResults returns a slice of AnalysisResult protos populated with data from the
// experiment.
func (a *Analyzer) AnalysisResults() []*cpb.AnalysisResult {
	ret := []*cpb.AnalysisResult{}
	// Because ExperimentSpec will have so many identical
	// values across individual results, we'll build a template here
	// then clone and override the distinct per-result values for the
	// response proto below.
	//
	// Note that for most Pinpoint A/B tryjobs, the ExperimentSpec will
	// have a Common RunSpec set, and Treatment and Control will have different BuildSpec values.
	// That is, compare two different builds executing on the same hardware/OS.
	experimentSpecTemplate := a.experimentSpec
	if experimentSpecTemplate.Analysis == nil {
		experimentSpecTemplate.Analysis = &cpb.AnalysisSpec{}
	}
	experimentSpecTemplate.Analysis.Benchmark = nil

	sort.Sort(byBenchmarkAndWorkload(a.results))

	for _, res := range a.results {
		experimentSpec := proto.Clone(experimentSpecTemplate).(*cpb.ExperimentSpec)
		benchmark := []*cpb.Benchmark{
			{
				Name:     res.Benchmark,
				Workload: []string{res.WorkLoad},
			},
		}

		experimentSpec.Analysis.Benchmark = benchmark

		ret = append(ret, &cpb.AnalysisResult{
			ExperimentSpec: experimentSpec,
			Statistic: &cpb.Statistic{
				Upper:           res.Statistics.UpperCi,
				Lower:           res.Statistics.LowerCi,
				PValue:          res.Statistics.PValue,
				ControlMedian:   res.Statistics.YMedian,
				TreatmentMedian: res.Statistics.XMedian,
			},
		})
	}
	return ret
}

type byBenchmarkAndWorkload []Results

func (a byBenchmarkAndWorkload) Len() int      { return len(a) }
func (a byBenchmarkAndWorkload) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byBenchmarkAndWorkload) Less(i, j int) bool {
	if a[i].Benchmark != a[j].Benchmark {
		return a[i].Benchmark < a[j].Benchmark
	}
	return a[i].WorkLoad < a[j].WorkLoad
}

func (a *Analyzer) ExperimentSpec() *cpb.ExperimentSpec {
	return a.experimentSpec
}

// Run executes the whole Analyzer process for a single, complete experiment.
// TODO(seanmccullough): break this up into distinct, testable stages with one function per stage.
func (a *Analyzer) Run(ctx context.Context) ([]Results, error) {
	ctx, span := trace.StartSpan(ctx, "Analyzer_Run")
	defer span.End()

	var control, treatment []float64
	var benchmark, workload, buildspec, runspec []string
	var replicas []int

	res := []Results{}

	allTaskInfos, err := a.readSwarmingTasks(ctx, a.pinpointJobID)
	if err != nil {
		return res, err
	}

	// TODO(seanmccullough): choose different process<Foo>Tasks implementations based on AnalysisSpec values.
	processedArms, err := a.processPinpointTryjobTasks(allTaskInfos)
	if err != nil {
		return res, err
	}
	err = a.extractTaskOutputs(ctx, processedArms)
	if err != nil {
		return res, err
	}

	// TODO(seanmccullough): include pairing order information so we keep track of which arm executed first in
	// every pairing.
	pairs, err := processedArms.pairedTasks(a.diagnostics.ExcludedSwarmingTasks)
	if err != nil {
		return res, err
	}

	if a.experimentSpec == nil {
		ieSpec, err := a.inferExperimentSpec(pairs)
		if err != nil {
			sklog.Errorf("while trying to infer experiment spec: %v", err)
			return res, err
		}

		a.experimentSpec = ieSpec
	}

	transformType := cabe_stats.LogTransform

	for replicaNumber, pair := range pairs {
		// Check task result codes to identify and handle task failures (which are expected; lab hardware is inherently unreliable).
		if pair.hasTaskFailures() {
			a.diagnostics.excludeReplica(replicaNumber, pair, "one or both tasks failed")
			continue
		}
		pairIsOk := true
		for _, benchmarkSpec := range a.experimentSpec.Analysis.Benchmark {
			controlResults, crOk := pair.control.parsedResults[benchmarkSpec.Name]
			treatmentResults, trOk := pair.treatment.parsedResults[benchmarkSpec.Name]
			if !crOk || !trOk {
				a.diagnostics.excludeReplica(replicaNumber, pair, fmt.Sprintf("one or both tasks are missing output for entire benchmark %q", benchmarkSpec.Name))
				pairIsOk = false
				continue
			}
			expectedWorkloads := util.NewStringSet(benchmarkSpec.Workload)
			missingFromCtrl := expectedWorkloads.Complement(util.NewStringSet(controlResults.NonEmptyHistogramNames()))
			missingFromTrt := expectedWorkloads.Complement(util.NewStringSet(treatmentResults.NonEmptyHistogramNames()))
			if len(missingFromCtrl) != 0 {
				a.diagnostics.excludeReplica(replicaNumber, pair, fmt.Sprintf("control task %s on bot %s is missing output for benchmark %s: workload(s) %v",
					pair.control.taskID, pair.control.taskInfo.TaskResult.BotId, benchmarkSpec.Name, missingFromCtrl))
				pairIsOk = false
			}
			if len(missingFromTrt) != 0 {
				a.diagnostics.excludeReplica(replicaNumber, pair, fmt.Sprintf("treatment task %s on bot %s is missing output for benchmark %s workload(s) %v",
					pair.treatment.taskID, pair.treatment.taskInfo.TaskResult.BotId, benchmarkSpec.Name, missingFromTrt))
				pairIsOk = false
			}
		}
		if !pairIsOk {
			continue
		}
		controlTask, treatmentTask := pair.control, pair.treatment

		runSpecName := pair.control.runConfig
		buildSpecName := pair.control.buildConfig
		for _, benchmarkSpec := range a.experimentSpec.GetAnalysis().GetBenchmark() {
			cRes := controlTask.parsedResults[benchmarkSpec.GetName()]
			tRes := treatmentTask.parsedResults[benchmarkSpec.GetName()]

			for _, workloadName := range benchmarkSpec.GetWorkload() {

				cValues := cRes.GetSampleValues(workloadName)
				if len(cValues) == 0 {
					msg := fmt.Sprintf("control task %s is missing %q/%q or reported an empty list of samples", pair.control.taskID, benchmarkSpec.GetName(), workloadName)
					a.diagnostics.excludeReplica(replicaNumber, pair, msg)
					continue
				}

				tValues := tRes.GetSampleValues(workloadName)
				if len(tValues) == 0 {
					msg := fmt.Sprintf("treatment task %s is missing %q/%q or reported an empty list of samples", pair.control.taskID, benchmarkSpec.GetName(), workloadName)
					a.diagnostics.excludeReplica(replicaNumber, pair, msg)
					continue
				}

				a.diagnostics.includeReplica(replicaNumber, pair)

				cMean := stat.Mean(cValues)
				tMean := stat.Mean(tValues)
				if tMean <= 0.0 || cMean <= 0.0 {
					sklog.Infof("detected values less than or equal to zero in measurement data, using NomralizeResult instead of LogTransform")
					transformType = cabe_stats.NormalizeResult
				}
				benchmark = append(benchmark, benchmarkSpec.GetName())
				workload = append(workload, workloadName)
				buildspec = append(buildspec, buildSpecName)
				runspec = append(runspec, runSpecName)
				replicas = append(replicas, replicaNumber)
				control = append(control, cMean)
				treatment = append(treatment, tMean)
			}
		}
	}

	// Group control/treatment pairs by [benchmark, workload, buildspec, runspec], aggregated over [replicas]
	// such that we end up with a map of [benchmark, workload, buildspec, runspec] to lists of [control, treatment] ordered by replica number within the lists
	type groupKey struct{ benchmark, workload, buildspec, runspec string }
	type tcPair struct{ control, treatment float64 }
	aggregateOverReplicas := map[groupKey]map[int]*tcPair{}

	for i, replicaNumber := range replicas {
		gk := groupKey{benchmark[i], workload[i], buildspec[i], runspec[i]}
		tcps := aggregateOverReplicas[gk]
		if tcps == nil {
			tcps = map[int]*tcPair{}
			aggregateOverReplicas[gk] = tcps
		}
		if tcps[replicaNumber] != nil {
			return res, fmt.Errorf("should not have a treatment/control pair aggregate for replica %d yet", replicaNumber)
		}
		tcps[replicaNumber] = &tcPair{control: control[i], treatment: treatment[i]}
	}

	for gk, tcps := range aggregateOverReplicas {
		ctrls, trts := []float64{}, []float64{}

		for _, tcp := range tcps {
			ctrls = append(ctrls, tcp.control)
			trts = append(trts, tcp.treatment)
		}
		r, err := cabe_stats.BerfWilcoxonSignedRankedTest(trts, ctrls, cabe_stats.TwoSided, transformType)
		if err != nil {
			sklog.Errorf("cabe_stats.BerfWilcoxonSignedRankedTest returned an error (%q), "+
				"printing the table of parameters passed to it below:",
				err)
			return res, errors.Wrap(err, "problem reported by cabe_stats.BerfWilcoxonSignedRankedTest")
		}
		res = append(res, Results{
			Benchmark:   gk.benchmark,
			WorkLoad:    gk.workload,
			BuildConfig: gk.buildspec,
			RunConfig:   gk.runspec,
			Statistics:  r,
		})
	}

	a.results = res
	return res, nil
}

// RunChecker verifies some assumptions we need to make about the experiment data input for
// our analyses.
func (a *Analyzer) RunChecker(ctx context.Context, c Checker) error {
	allTaskInfos, err := a.readSwarmingTasks(ctx, a.pinpointJobID)
	if err != nil {
		return err
	}

	for _, taskInfo := range allTaskInfos {
		c.CheckSwarmingTask(taskInfo)
	}

	processedTasks, err := a.processPinpointTryjobTasks(allTaskInfos)
	if err != nil {
		sklog.Errorf("RunChecker: processPinpointTryjobTasks returned %v", err)
		return err
	}

	err = a.extractTaskOutputs(ctx, processedTasks)
	if err != nil {
		sklog.Errorf("RunChecker: extractTaskOutputs returned %v", err)
		return err
	}

	pairs, err := processedTasks.pairedTasks(a.diagnostics.ExcludedSwarmingTasks)
	if err != nil {
		sklog.Errorf("RunChecker: processedTasks.pairedTasks() returned %v", err)
		return err
	}

	if a.experimentSpec == nil {
		ieSpec, err := a.inferExperimentSpec(pairs)
		if err != nil {
			sklog.Errorf("while trying to infer experiment spec: %v", err)
			return err
		}

		a.experimentSpec = ieSpec
	}

	for _, taskInfo := range allTaskInfos {
		c.CheckRunTask(taskInfo)
	}

	c.CheckArmComparability(processedTasks.control, processedTasks.treatment)

	return nil
}

func (a *Analyzer) inferExperimentSpec(pairs []pairedTasks) (*cpb.ExperimentSpec, error) {
	controlTaskResults, treatmentTaskResults := []map[string]perfresults.PerfResults{}, []map[string]perfresults.PerfResults{}
	controlArmSpecs, treatmentArmSpecs := []*cpb.ArmSpec{}, []*cpb.ArmSpec{}
	for replicaNumber, pair := range pairs {
		if pair.hasTaskFailures() {
			sklog.Infof("excluding replica %d from spec inference because it contains failures", replicaNumber)
			continue
		}

		controlTaskResults = append(controlTaskResults, pair.control.parsedResults)
		treatmentTaskResults = append(treatmentTaskResults, pair.treatment.parsedResults)
		cSpec, err := inferArmSpec(pair.control.taskInfo)
		if err != nil {
			return nil, err
		}
		controlArmSpecs = append(controlArmSpecs, cSpec)
		tSpec, err := inferArmSpec(pair.treatment.taskInfo)
		if err != nil {
			return nil, err
		}
		treatmentArmSpecs = append(treatmentArmSpecs, tSpec)
	}

	experimentSpec, err := inferExperimentSpec(controlArmSpecs, treatmentArmSpecs, controlTaskResults, treatmentTaskResults)
	if err != nil {
		return nil, err
	}

	return experimentSpec, nil
}

func (a *Analyzer) extractTaskOutputs(ctx context.Context, processedArms *processedExperimentTasks) error {
	// This is currently un-sliced. As in, it lumps all runconfigs together. This is fine if you only
	// have one runconfig (say, you only asked to analyze Mac results).
	// TODO(seanmccullough): add slicing, which will nest the code below inside an iterator over the slices.

	// Fetch outputs from control and treatment arms in parallel since there is no data dependency between them.
	g, ctx := errgroup.WithContext(ctx)
	g.Go(func() error {
		ctx, span := trace.StartSpan(ctx, "Analyzer_extractTaskOutputs_control")
		defer span.End()

		controlDigests := map[int]*apipb.CASReference{}
		for n, t := range processedArms.control.tasks {
			if t.taskInfo.TaskResult.State != apipb.TaskState_COMPLETED {
				continue
			}
			controlDigests[n] = t.taskInfo.TaskResult.CasOutputRoot
		}
		controlReplicaOutputs, err := a.fetchOutputsFromReplicas(ctx, controlDigests)
		if err != nil {
			return err
		}
		for replica, results := range controlReplicaOutputs {
			processedArms.control.tasks[replica].parsedResults = results
		}
		return nil
	})

	g.Go(func() error {
		ctx, span := trace.StartSpan(ctx, "Analyzer_extractTaskOutputs_treatment")
		defer span.End()

		treatmentDigests := map[int]*apipb.CASReference{}
		for n, t := range processedArms.treatment.tasks {
			if t.taskInfo.TaskResult.State != apipb.TaskState_COMPLETED {
				continue
			}
			treatmentDigests[n] = t.taskInfo.TaskResult.CasOutputRoot
		}
		treatmentReplicaOutputs, err := a.fetchOutputsFromReplicas(ctx, treatmentDigests)
		if err != nil {
			return err
		}
		for replica, results := range treatmentReplicaOutputs {
			processedArms.treatment.tasks[replica].parsedResults = results
		}
		return nil
	})

	if err := g.Wait(); err != nil {
		return err
	}

	return nil
}

// returns a slice of maps of perfresults.PerfResults files keyed by benchmark name.
func (a *Analyzer) fetchOutputsFromReplicas(ctx context.Context, outputs map[int]*apipb.CASReference) (map[int]map[string]perfresults.PerfResults, error) {
	ret := make(map[int]map[string]perfresults.PerfResults, len(outputs))
	g, ctx := errgroup.WithContext(ctx)
	if len(outputs) > maxReadCASPoolWorkers {
		g.SetLimit(maxReadCASPoolWorkers)
	} else {
		g.SetLimit(len(outputs))
	}

	retMu := &sync.Mutex{}

	for replica, casRef := range outputs {
		replica := replica
		casRef := casRef
		g.Go(func() error {
			ctx, span := trace.StartSpan(ctx, "Analyzer_fetchOutputsFromReplicas_readOutput")
			defer span.End()

			if casRef.Digest == nil {
				sklog.Error("missing CAS reference for replica %d", replica)
				return fmt.Errorf("missing CAS reference for replica %d", replica)
			}
			casDigest, err := digest.New(casRef.Digest.Hash, casRef.Digest.SizeBytes)
			if err != nil {
				sklog.Errorf("digest.New: %v", err)
				return err
			}
			span.AddAttributes(trace.StringAttribute("digest", casDigest.String()))
			res, err := a.readCAS(ctx, casRef.CasInstance, casDigest.String())
			if err != nil {
				sklog.Errorf("e.readCAS: %v", err)
				return err
			}
			retMu.Lock()
			defer retMu.Unlock()
			ret[replica] = res
			return nil
		})
	}

	if err := g.Wait(); err != nil {
		sklog.Errorf("fetchOutputsFromReplicas: %v", err)
		return nil, err
	}

	return ret, nil
}

// Split apipb.TaskRequestMetadataResponses into experiment arms and pair tasks according to how they should be
// compared in the analysis/hypothesis testing phase.
// The slice of tasks should be a complete list of all the tasks for an experiment, and they should
// all have completed executing successfully.
func (a *Analyzer) processPinpointTryjobTasks(tasks []*apipb.TaskRequestMetadataResponse) (*processedExperimentTasks, error) {
	ret := &processedExperimentTasks{
		treatment: &processedArmTasks{},
		control:   &processedArmTasks{},
	}

	buildTasks := map[string]*buildInfo{}
	sklog.Infof("splitting %d swarming tasks into control and treatment arms", len(tasks))
	for _, task := range tasks {
		// First check if we have a build task. It doesn't run any benchmarks, but it does build the
		// binaries for running benchmarks. So we need to keep track of it for BuildSpec details later.
		buildInfo, err := buildInfoForTask(task)
		if err != nil {
			msg := fmt.Sprintf("task.buildInfo(): %v", err)
			sklog.Error(msg)
			a.diagnostics.excludeSwarmingTask(task, msg)
		}
		if buildInfo != nil {
			buildTasks[task.TaskId] = buildInfo
			// Just move on to processing the next task now that we know this was a build task.
			continue
		}

		// err should not be nil if the task is not a run task.
		runInfo, err := runInfoForTask(task)
		if err != nil {
			msg := fmt.Sprintf("runInfoForTask: %v", err)
			sklog.Error(msg)
			a.diagnostics.excludeSwarmingTask(task, msg)
		}

		if task.TaskResult.State != apipb.TaskState_COMPLETED {
			msg := fmt.Sprintf("task result is in state %q, not %q", task.TaskResult.State, taskCompletedState)
			a.diagnostics.excludeSwarmingTask(task, msg)
		} else {
			a.diagnostics.includeSwarmingTask(task)
			// If it's not a build task, assume it's a test runner task.
			// Get the CAS digest for the task output so we can fetch it later.
			if task.TaskResult.CasOutputRoot == nil || task.TaskResult.CasOutputRoot.Digest == nil {
				return nil, fmt.Errorf("run task result missing CasOutputRoot: %+v", task)
			}
		}

		t := &armTask{
			taskID:       task.TaskId,
			resultOutput: task.TaskResult.CasOutputRoot,
			buildInfo:    buildInfo,
			runConfig:    runInfo.String(),
			taskInfo:     task,
		}

		// For pinpoint tryjobs, the following assumptions should hold true:
		// treatment has a tag like "change:exp: chromium@d879632 + 0dd4ae0 (Variant: 1)"
		// control has a tag like "change:base: chromium@d879632 (Variant: 0)"
		change := pinpointChangeTagForTask(task)
		if change == "" {
			return nil, fmt.Errorf("missing pinpoint change tag: %+v", task)
		}
		if strings.HasPrefix(change, "exp:") {
			if ret.treatment.pinpointChangeTag == "" {
				ret.treatment.pinpointChangeTag = change
			}
			if change != ret.treatment.pinpointChangeTag {
				return nil, fmt.Errorf("mismatched change tag for treatment arm. Got %q but expected %q", change, ret.treatment.pinpointChangeTag)
			}
			ret.treatment.tasks = append(ret.treatment.tasks, t)
		} else if strings.HasPrefix(change, "base:") {
			if ret.control.pinpointChangeTag == "" {
				ret.control.pinpointChangeTag = change
			}
			if change != ret.control.pinpointChangeTag {
				return nil, fmt.Errorf("mismatched change tag for control arm. Got %q but expected %q", change, ret.control.pinpointChangeTag)
			}
			ret.control.tasks = append(ret.control.tasks, t)
		} else if len(strings.Split(change, "@")) == 2 {
			// This might be from a bisect job, where control and treatment are builds from two different commit positions on a main branch.
			// TODO(seanmccullough): also check for "comparison_mode:performance" tags on these tasks.
			parts := strings.Split(change, "@")
			repo := parts[0]
			cp := parts[1]
			return nil, fmt.Errorf("unsupported yet: changes that only identify repo and commit position: %v @ %v", repo, cp)
		} else {
			return nil, fmt.Errorf("unrecognized change tag: %q", change)
		}
	}

	return ret, nil
}
