package tracestore

import (
	"context"
	"strings"
	"time"

	"go.skia.org/infra/go/paramtools"
	"go.skia.org/infra/go/query"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/tiling"
	"go.skia.org/infra/golden/go/types"
)

// Entry is one digests and related params to be added to the TraceStore.
type Entry struct {
	// Params describe the configuration that produced the digest/image.
	// These params will be used to form the trace id.
	Params map[string]string

	// Options give extra details about this trace. These options will be stored
	// tile by tile, with the most recent commit's options overwriting any
	// previous options. These details do not affect the trace id and are
	// largely considered to be FYI.
	Options map[string]string

	// Digest references the image that was generated by the test.
	// If two different Puts set a digest for a given commit + Params, the one
	// with the later timestamp will be kept.
	Digest types.Digest
}

// TraceStore is the interface to store trace data.
type TraceStore interface {
	// Put writes the given entries to the TraceStore at the given commit hash. The timestamp is
	// assumed to be the time when the entries were generated and will be used for the digests.
	// It is undefined behavior to have multiple entries with the exact same Params.
	Put(ctx context.Context, commitHash string, entries []*Entry, ts time.Time) error

	// GetTile reads the last n commits and returns them as a tile.
	// The second return value is all commits that are in the tile.
	GetTile(ctx context.Context, nCommits int) (*tiling.Tile, []*tiling.Commit, error)

	// GetDenseTile constructs a tile containing only commits that have data for at least one trace.
	// The returned tile will always have length exactly nCommits unless there are fewer than
	// nCommits commits with data. The second return value contains all commits starting with the
	// first commit of the tile and ending with the most recent commit, in order; i.e. it includes
	// all commits in the tile as well as the omitted commits.
	GetDenseTile(ctx context.Context, nCommits int) (*tiling.Tile, []*tiling.Commit, error)
}

// TraceIDFromParams deterministically returns a TraceId that uniquely encodes
// the given params. It follows the same convention as perf's trace ids, that
// is something like ",key1=value1,key2=value2,...," where the keys
// are in alphabetical order.
func TraceIDFromParams(params paramtools.Params) tiling.TraceId {
	// Clean up any params with , or =
	params = forceValid(params)
	s, err := query.MakeKeyFast(params)
	if err != nil {
		sklog.Warningf("Invalid params passed in for trace id %#v: %s", params, err)
	}
	return tiling.TraceId(s)
}

// clean replaces any special runes (',', '=') in a string such that
// they can be turned into a trace id, which uses those special runes
// as dividers.
func clean(s string) string {
	// In most cases, traces will be valid, so check that first.
	// Allocating the string buffer and copying the runes can be expensive
	// when done for no reason.
	bad := false
	for _, c := range s {
		if c == ',' || c == '=' {
			bad = true
			break
		}
	}
	if !bad {
		return s
	}
	sb := strings.Builder{}
	sb.Grow(len(s))
	// Regexp doesn't handle being run from a large number of go routines
	// very well. See https://github.com/golang/go/issues/8232.
	for _, c := range s {
		if c == ',' || c == '=' {
			sb.WriteRune('_')
		} else {
			sb.WriteRune(c)
		}
	}
	return sb.String()
}

// forceValid ensures that the resulting map will make a valid structured key.
func forceValid(m map[string]string) map[string]string {
	ret := make(map[string]string, len(m))
	for key, value := range m {
		ret[clean(key)] = clean(value)
	}

	return ret
}
