package calc

import (
	"fmt"
	"math"
	"strconv"

	"go.skia.org/infra/go/vec32"
	"go.skia.org/infra/perf/go/types"
)

const (
	// MIN_STDDEV is the smallest standard deviation we will normalize, smaller
	// than this and we presume it's a standard deviation of zero.
	MIN_STDDEV = 0.001
)

// applyFuncToEachColumn applies the given func 'f' to each column in the given TraceSet.
func applyFuncToEachColumn(rows types.TraceSet, f func(column []float32) float32) types.Trace {
	ret := newRow(types.TraceSet(rows))
	for i := range ret {
		column := vec32.New(len(rows))
		colIndex := 0
		for _, r := range rows {
			column[colIndex] = r[i]
			colIndex++
		}
		ret[i] = f(column)
	}
	return ret
}

type FilterFunc struct{}

// filterFunc is a Func that returns a filtered set of Rows in the Context.
//
// It expects a single argument that is a string in URL query format, ala
// os=Ubuntu12&config=8888.
func (FilterFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("filter() takes a single argument.")
	}
	if node.Args[0].Typ != NodeString {
		return nil, fmt.Errorf("filter() takes a string argument.")
	}
	return ctx.RowsFromQuery(node.Args[0].Val)
}

func (FilterFunc) Describe() string {
	return `filter() returns a filtered set of Rows that match the given query.

  It expects a single argument that is a string in URL query format, such as:

     os=Ubuntu12&config=8888.`
}

var filterFunc = FilterFunc{}

type ShortcutFunc struct{}

// shortcutFunc is a Func that returns a set of Rows in the Context.
//
// It expects a single argument that is a shortcut id.
func (ShortcutFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("shortcut() takes a single argument.")
	}
	if node.Args[0].Typ != NodeString {
		return nil, fmt.Errorf("shortcut() takes a string argument.")
	}
	if ctx.RowsFromShortcut == nil {
		return nil, fmt.Errorf("shortcut() is not available.")
	}
	return ctx.RowsFromShortcut(node.Args[0].Val)
}

func (ShortcutFunc) Describe() string {
	return `shortcut() returns a set of Rows that match the given shortcut id.

  It expects a single argument that is the id of a shortcut set of traces. `
}

var shortcutFunc = ShortcutFunc{}

type NormFunc struct{}

// normFunc implements Func and normalizes the traces to a mean of 0 and a
// standard deviation of 1.0. If a second optional number is passed in to
// norm() then that is used as the minimum standard deviation that is
// normalized, otherwise it defaults to MIN_STDDEV.
func (NormFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) > 2 || len(node.Args) == 0 {
		return nil, fmt.Errorf("norm() takes one or two arguments.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("norm() takes a function as its first argument.")
	}
	minStdDev := MIN_STDDEV
	if len(node.Args) == 2 {
		if node.Args[1].Typ != NodeNum {
			return nil, fmt.Errorf("norm() takes a number as its second argument.")
		}
		var err error
		minStdDev, err = strconv.ParseFloat(node.Args[1].Val, 32)
		if err != nil {
			return nil, fmt.Errorf("norm() stddev not a valid number %s : %s", node.Args[1].Val, err)
		}
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("norm() failed evaluating argument: %s", err)
	}

	ret := types.TraceSet{}
	for key, r := range rows {
		row := vec32.Dup(r)
		vec32.Norm(row, float32(minStdDev))
		ret["norm("+key+")"] = row
	}

	return ret, nil
}

func (NormFunc) Describe() string {
	return `norm() normalizes the rows to a mean of 0 and a standard deviation of 1.0.

  If a second optional number is passed in to
  norm() then that is used as the minimum standard deviation that is
  normalized, otherwise it defaults to 0.1.`
}

var normFunc = NormFunc{}

type FillFunc struct{}

// fillFunc implements Func and fills in all the missing datapoints with nearby
// points.
//
// Note that a Row with all vec32.MISSING_DATA_SENTINEL values will be filled with
// 0's.
func (FillFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("fill() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("fill() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("fill() failed evaluating argument: %s", err)
	}

	ret := types.TraceSet{}
	for key, r := range rows {
		row := vec32.Dup(r)
		vec32.Fill(row)
		ret["fill("+key+")"] = row
	}
	return ret, nil
}

func (FillFunc) Describe() string {
	return `fill() fills in all the missing datapoints with nearby points.`
}

var fillFunc = FillFunc{}

type AveFunc struct{}

// aveFunc implements Func and averages the values of all argument
// traces into a single trace.
//
// vec32.MISSING_DATA_SENTINEL values are not included in the average.  Note that if
// all the values at an index are vec32.MISSING_DATA_SENTINEL then the average will
// be vec32.MISSING_DATA_SENTINEL.
func (AveFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("ave() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("ave() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("ave() argument failed to evaluate: %s", err)
	}

	if len(rows) == 0 {
		return rows, nil
	}

	retRow := AveFuncImpl(types.TraceSet(rows))
	return types.TraceSet{ctx.formula: retRow}, nil
}

// AveFuncImpl averages the values of all argument traces into a single trace.
func AveFuncImpl(rows types.TraceSet) types.Trace {
	ret := newRow(types.TraceSet(rows))
	for i := range ret {
		sum := float32(0.0)
		count := 0
		for _, r := range rows {
			if v := r[i]; v != vec32.MissingDataSentinel {
				sum += v
				count++
			}
		}
		if count > 0 {
			ret[i] = sum / float32(count)
		}
	}
	return ret
}

func (AveFunc) Describe() string {
	return `ave() averages the values of all argument rows into a single trace.`
}

var aveFunc = AveFunc{}

type RatioFunc struct{}

func (RatioFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 2 {
		return nil, fmt.Errorf("ratio() takes two arguments")
	}

	rowsA, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("ratio() argument failed to evaluate: %s", err)
	}
	rowA := []float32{}
	for _, v := range rowsA {
		rowA = v
		break
	}

	rowsB, err := node.Args[1].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("ratio() argument failed to evaluate: %s", err)
	}
	rowB := []float32{}
	for _, v := range rowsB {
		rowB = v
		break
	}

	ret := newRow(rowsA)
	for i := range ret {
		ret[i] = rowA[i] / rowB[i]
		if math.IsInf(float64(ret[i]), 0) {
			ret[i] = vec32.MissingDataSentinel
		}
	}
	return types.TraceSet{ctx.formula: ret}, nil
}

func (RatioFunc) Describe() string {
	return `ratio(a, b) returns the point by point ratio of two rows.
                That is, it returns a trace with a[i]/b[i] for every point in a and b.`
}

var ratioFunc = RatioFunc{}

// CountFunc implements Func and counts the number of non-sentinel values in
// all argument rows.
//
// vec32.MISSING_DATA_SENTINEL values are not included in the count.  Note that if
// all the values at an index are vec32.MISSING_DATA_SENTINEL then the count will
// be 0.
type CountFunc struct{}

func (CountFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("count() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("count() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("count() argument failed to evaluate: %s", err)
	}

	if len(rows) == 0 {
		return rows, nil
	}

	retRow := CountFuncImpl(rows)
	return types.TraceSet{ctx.formula: retRow}, nil
}

func (CountFunc) Describe() string {
	return `count() counts the non-missing values of all argument rows.`
}

var countFunc = CountFunc{}

func CountFuncImpl(rows types.TraceSet) types.Trace {
	return applyFuncToEachColumn(rows, vec32.Count)
}

type SumFunc struct{}

// SumFunc implements Func and sums the values of all argument
// rows into a single trace.
//
// vec32.MISSING_DATA_SENTINEL values are not included in the sum. Note that if all
// the values at an index are vec32.MISSING_DATA_SENTINEL then the sum will be
// vec32.MISSING_DATA_SENTINEL.
func (SumFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("sum() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("sum() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("Sum() argument failed to evaluate: %s", err)
	}

	if len(rows) == 0 {
		return rows, nil
	}

	retRow := SumFuncImpl(types.TraceSet(rows))
	return types.TraceSet{ctx.formula: retRow}, nil
}

// SumFuncImpl sums the values of all argument rows into a single trace.
func SumFuncImpl(rows types.TraceSet) types.Trace {
	return applyFuncToEachColumn(rows, vec32.SumE)
}

func (SumFunc) Describe() string {
	return `Sum() Sums the values of all argument rows into a single trace.`
}

var sumFunc = SumFunc{}

type GeoFunc struct{}

// geoFunc implements Func and merges the values of all argument
// rows into a single trace with a geometric mean.
//
// vec32.MISSING_DATA_SENTINEL and negative values are not included in the mean.
// Note that if all the values at an index are vec32.MISSING_DATA_SENTINEL or
// negative then the mean will be vec32.MISSING_DATA_SENTINEL.
func (GeoFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("geo() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("geo() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("geo() argument failed to evaluate: %s", err)
	}

	if len(rows) == 0 {
		return rows, nil
	}

	retRow := GeoFuncImpl(rows)
	return types.TraceSet{ctx.formula: retRow}, nil
}

func (GeoFunc) Describe() string {
	return `geo() folds the values of all argument rows into a single geometric mean trace.`
}

var geoFunc = GeoFunc{}

// GeoFuncImpl take the geometric mean of the values of all argument rows into a single trace.
func GeoFuncImpl(rows types.TraceSet) types.Trace {
	return applyFuncToEachColumn(rows, vec32.GeoE)
}

type LogFunc struct{}

// logFunc implements Func and transforms a row of x into a row of log10(x).
//
// Values <= 0 are set to vec32.MISSING_DATA_SENTINEL.  vec32.MISSING_DATA_SENTINEL values are left untouched.
func (LogFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("log() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("log() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("log() failed evaluating argument: %s", err)
	}

	for j, r := range rows {
		row := vec32.Dup(r)
		for i, v := range row {
			if v != vec32.MissingDataSentinel {
				if v > 0 {
					row[i] = float32(math.Log10(float64(v)))
				} else {
					row[i] = vec32.MissingDataSentinel
				}
			}
		}
		rows[j] = row
	}
	// TODO rename the rows
	return rows, nil
}

func (LogFunc) Describe() string {
	return `log() applies a base-10 logarithm to the datapoints.`
}

var logFunc = LogFunc{}

type TraceAveFunc struct{}

// traceAveFunc implements Func and Computes the mean for all the values in a trace and return a trace where every value is that mean.
//
// vec32.MISSING_DATA_SENTINEL values are not taken into account for the ave. If the entire vector is vec32.MISSING_DATA_SENTINEL then
// the result is also all vec32.MISSING_DATA_SENTINEL.
func (TraceAveFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("trace_ave() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("trace_ave() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("trace_ave() failed evaluating argument: %s", err)
	}

	ret := types.TraceSet{}
	for key, r := range rows {
		row := vec32.Dup(r)
		vec32.FillMeanMissing(row)
		ret["trace_ave("+key+")"] = row
	}

	return ret, nil
}

func (TraceAveFunc) Describe() string {
	return `Computes the mean for all the values in a trace and return a trace where every value is that mean.`
}

var traceAveFunc = TraceAveFunc{}

type TraceStdDevFunc struct{}

// traceStdDevFunc implements Func and Computes the std dev for all the values in a trace and return a trace where every value is that std dev.
//
// vec32.MISSING_DATA_SENTINEL values are not taken into account for the ave. If the entire vector is vec32.MISSING_DATA_SENTINEL then
// the result is also all vec32.MISSING_DATA_SENTINEL.
func (TraceStdDevFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("trace_stddev() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("trace_stddev() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("trace_stddev() failed evaluating argument: %s", err)
	}

	ret := types.TraceSet{}
	for key, r := range rows {
		row := vec32.Dup(r)
		vec32.FillStdDev(row)
		ret["trace_stddev("+key+")"] = row
	}

	return ret, nil
}

func (TraceStdDevFunc) Describe() string {
	return `Computes the std dev for all the values in a trace and return a trace where every value is that stddev.`
}

var traceStdDevFunc = TraceStdDevFunc{}

type TraceCovFunc struct{}

// traceCovFunc implements Func and Computes the Coefficient of Variation (std dev)/mean for all the values in a trace and return a trace where every value is the CoV.
//
// vec32.MISSING_DATA_SENTINEL values are not taken into account for the ave. If the entire vector is vec32.MISSING_DATA_SENTINEL then
// the result is also all vec32.MISSING_DATA_SENTINEL.
func (TraceCovFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("trace_cov() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("trace_cov() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("trace_cov() failed evaluating argument: %s", err)
	}

	ret := types.TraceSet{}
	for key, r := range rows {
		row := vec32.Dup(r)
		vec32.FillCov(row)
		ret["trace_cov("+key+")"] = row
	}

	return ret, nil
}

func (TraceCovFunc) Describe() string {
	return `Computes the Coefficient of Variation for all the values in a trace and return a trace where every value is that CoV.`
}

var traceCovFunc = TraceCovFunc{}

type TraceStepFunc struct{}

// TraceStepFunc implements Func and Computes the step function, i.e the ratio of the ave of the first half of the trace divided
// by the ave of the second half of the trace.
//
// vec32.MISSING_DATA_SENTINEL values are not taken into account for the ave. If the entire vector is vec32.MISSING_DATA_SENTINEL then
// the result is also all vec32.MISSING_DATA_SENTINEL.
func (TraceStepFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("trace_step() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("trace_step() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("trace_step() failed evaluating argument: %s", err)
	}

	ret := types.TraceSet{}
	for key, r := range rows {
		row := vec32.Dup(r)
		vec32.FillStep(row)
		ret["trace_step("+key+")"] = row
	}

	return ret, nil
}

func (TraceStepFunc) Describe() string {
	return `Computes the step function, i.e the ratio of the ave of the first half of the trace divided by the ave of the second half of the trace.`
}

var traceStepFunc = TraceStepFunc{}

type ScaleByAveFunc struct{}

// ScaleByAveFunc implements Func and Computes a new trace that is scaled by 1/(average of all values in the trace).
//
// vec32.MISSING_DATA_SENTINEL values are not taken into account for the ave. If the entire vector is vec32.MISSING_DATA_SENTINEL then
// the result is also all vec32.MISSING_DATA_SENTINEL.
func (ScaleByAveFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("scale_by_ave() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("scale_by_ave() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("scale_by_ave() failed evaluating argument: %s", err)
	}

	ret := types.TraceSet{}
	for key, r := range rows {
		row := vec32.Dup(r)
		mean := vec32.Mean(row)
		vec32.ScaleBy(row, mean)
		ret["scale_by_ave("+key+")"] = row
	}

	return ret, nil
}

func (ScaleByAveFunc) Describe() string {
	return `Computes a new trace t1Ghat is scaled by 1/(ave) where ave is the average of the input trace.`
}

var scaleByAveFunc = ScaleByAveFunc{}

// IQRRFunc implements Func and computes a new trace that is has all outliers
// set to MISSING_DATA_SENTINEL based on the interquartile range.
//
// vec32.MISSING_DATA_SENTINEL values are not taken into account when computing
// the outliers.
type IQRRFunc struct{}

func (IQRRFunc) Eval(ctx *Context, node *Node) (types.TraceSet, error) {
	if len(node.Args) != 1 {
		return nil, fmt.Errorf("iqrr() takes a single argument.")
	}
	if node.Args[0].Typ != NodeFunc {
		return nil, fmt.Errorf("iqrr() takes a function argument.")
	}
	rows, err := node.Args[0].Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("iqrr() failed evaluating argument: %s", err)
	}

	ret := types.TraceSet{}
	for key, r := range rows {
		row := vec32.Dup(r)
		vec32.IQRR(row)
		ret["iqrr("+key+")"] = row
	}

	return ret, nil
}

func (IQRRFunc) Describe() string {
	return `Computes a new trace that has all outliers removed by the interquartile rule.`
}

var iqrrFunc = IQRRFunc{}

// StdDevFuncImpl puts the std deviation of the values of all argument traces
// into a single trace.
func StdDevFuncImpl(rows types.TraceSet) types.Trace {
	return applyFuncToEachColumn(rows, func(column []float32) float32 {
		_, stddev, err := vec32.MeanAndStdDev(column)
		if err != nil {
			return vec32.MissingDataSentinel
		}
		return stddev
	})
}

// MaxFuncImpl puts the max of the values of all argument traces into a single
// trace.
func MaxFuncImpl(rows types.TraceSet) types.Trace {
	return applyFuncToEachColumn(rows, vec32.Max)
}

// MinFuncImpl puts the min of the values of all argument traces into a single
// trace.
func MinFuncImpl(rows types.TraceSet) types.Trace {
	return applyFuncToEachColumn(rows, vec32.Min)
}
