package expectations

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

	"go.skia.org/infra/golden/go/types"
)

// Expectations captures the expectations for a set of tests and digests as
// labels (Positive/Negative/Untriaged).
// Put another way, this data structure keeps track if a digest (image) is
// drawn correctly, incorrectly, or newly-seen for a given test.
// Expectations is thread safe.
type Expectations struct {
	mutex sync.RWMutex
	// TODO(kjlubick) Consider storing this as
	//   map[digestGrouping]Label where
	//   type digestGrouping struct {
	//     digest types.Digest
	//     grouping types.TestName
	//   }
	labels map[types.TestName]map[types.Digest]Label
}

// Baseline is a simplified view of the Expectations, suitable for JSON encoding. A Baseline only
// has entries with positive and negative labels (i.e. no untriaged entries).
type Baseline map[types.TestName]map[types.Digest]Label

// ReadOnly is an interface with the non-mutating functions of Expectations.
// By using this instead of Expectations, we can make fewer copies, helping performance.
type ReadOnly interface {
	Classifier
	// ForAll will iterate through all entries in Expectations and call the callback with them.
	// Iteration will stop if a non-nil error is returned (and will be forwarded to the caller).
	ForAll(fn func(types.TestName, types.Digest, Label) error) error

	// Empty returns true iff NumTests() == 0
	Empty() bool

	// NumTests returns the number of tests that Expectations knows about.
	NumTests() int

	// Len returns the number of test/digest pairs stored.
	Len() int
}

// Classifier is a simple interface for querying expectations.
type Classifier interface {
	// Classification returns the label for the given test/digest pair. By definition,
	// this will return Untriaged if there isn't already a classification set.
	Classification(test types.TestName, digest types.Digest) Label
}

// Set sets the label for a test_name/digest pair. If the pair already exists,
// it will be over written.
func (e *Expectations) Set(testName types.TestName, digest types.Digest, label Label) {
	e.mutex.Lock()
	defer e.mutex.Unlock()
	e.ensureInit()
	if digests, ok := e.labels[testName]; ok {
		if label == Untriaged {
			delete(digests, digest)
		} else {
			digests[digest] = label
		}
	} else {
		if label != Untriaged {
			e.labels[testName] = map[types.Digest]Label{digest: label}
		}
	}
}

// setDigests is a convenience function to set the expectations of a set of digests for a
// given test_name. Callers should have the write mutex locked.
func (e *Expectations) setDigests(testName types.TestName, labels map[types.Digest]Label) {
	digests, ok := e.labels[testName]
	if !ok {
		digests = make(map[types.Digest]Label, len(labels))
	}
	for digest, label := range labels {
		if label != Untriaged {
			digests[digest] = label
		}
	}
	e.labels[testName] = digests
}

// MergeExpectations adds the given expectations to the current expectations, letting
// the ones provided by the passed in parameter overwrite any existing data. Trying to merge
// two expectations into each other simultaneously may result in a dead-lock.
func (e *Expectations) MergeExpectations(other *Expectations) {
	if other == nil {
		return
	}
	other.mutex.RLock()
	defer other.mutex.RUnlock()
	e.mutex.Lock()
	defer e.mutex.Unlock()
	e.ensureInit()
	for testName, digests := range other.labels {
		e.setDigests(testName, digests)
	}
}

// ForAll implements the ReadOnly interface.
func (e *Expectations) ForAll(fn func(types.TestName, types.Digest, Label) error) error {
	e.mutex.RLock()
	defer e.mutex.RUnlock()
	for test, digests := range e.labels {
		for digest, label := range digests {
			err := fn(test, digest, label)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// DeepCopy makes a deep copy of the current expectations/baseline.
func (e *Expectations) DeepCopy() *Expectations {
	ret := Expectations{
		labels: make(map[types.TestName]map[types.Digest]Label, len(e.labels)),
	}
	ret.MergeExpectations(e)
	return &ret
}

// Classification implements the ReadOnly interface.
func (e *Expectations) Classification(test types.TestName, digest types.Digest) Label {
	e.mutex.RLock()
	defer e.mutex.RUnlock()
	if label, ok := e.labels[test][digest]; ok {
		return label
	}
	return Untriaged
}

// Empty implements the ReadOnly interface.
func (e *Expectations) Empty() bool {
	return e.NumTests() == 0
}

// NumTests implements the ReadOnly interface.
func (e *Expectations) NumTests() int {
	if e == nil {
		return 0
	}
	e.mutex.RLock()
	defer e.mutex.RUnlock()
	return len(e.labels)
}

// Len implements the ReadOnly interface.
func (e *Expectations) Len() int {
	if e == nil {
		return 0
	}
	e.mutex.RLock()
	defer e.mutex.RUnlock()
	n := 0
	for _, d := range e.labels {
		n += len(d)
	}
	return n
}

// String returns an alphabetically sorted string representation
// of this object.
func (e *Expectations) String() string {
	e.mutex.RLock()
	defer e.mutex.RUnlock()
	names := make([]string, 0, len(e.labels))
	for testName := range e.labels {
		names = append(names, string(testName))
	}
	sort.Strings(names)
	s := strings.Builder{}
	for _, testName := range names {
		digestMap := e.labels[types.TestName(testName)]
		digests := make([]string, 0, len(digestMap))
		for d := range digestMap {
			digests = append(digests, string(d))
		}
		sort.Strings(digests)
		_, _ = fmt.Fprintf(&s, "%s:\n", testName)
		for _, d := range digests {
			_, _ = fmt.Fprintf(&s, "\t%s : %s\n", d, digestMap[types.Digest(d)])
		}
	}
	return s.String()
}

// AsBaseline returns a copy that has all untriaged digests removed.
func (e *Expectations) AsBaseline() Baseline {
	e.mutex.RLock()
	defer e.mutex.RUnlock()
	n := Expectations{
		labels: map[types.TestName]map[types.Digest]Label{},
	}
	for testName, digests := range e.labels {
		for d, c := range digests {
			if c != Untriaged {
				n.Set(testName, d, c)
			}
		}
	}
	return n.labels
}

// ensureInit expects that the write mutex is held prior to entry.
func (e *Expectations) ensureInit() {
	if e.labels == nil {
		e.labels = map[types.TestName]map[types.Digest]Label{}
	}
}

// JoinedExp represents a chain of ReadOnly that could contain Labels.
// The Expectations at the beginning of the list override those that follow.
type JoinedExp []ReadOnly

// Join returns a Classifier that combines the given ReadOnly. If multiple ReadOnly have a
// Label for a given Grouping (Test+Digest), the order of the ReadOnly will break the tie by
// using the ReadOnly which was provided first.
func Join(first, second ReadOnly, others ...ReadOnly) JoinedExp {
	rv := []ReadOnly{first, second}
	rv = append(rv, others...)
	return rv
}

// Classification returns the first non-untriaged label for the given
// test and digest. If none of the given ReadOnly have a match, Untriaged is returned.
func (e JoinedExp) Classification(test types.TestName, digest types.Digest) Label {
	for _, exp := range e {
		if label := exp.Classification(test, digest); label != Untriaged {
			return label
		}
	}
	return Untriaged
}

// EmptyClassifier returns a Classifier which returns Untriaged for given input.
// Mostly used for testing.
func EmptyClassifier() Classifier {
	return JoinedExp{}
}
