// tally returns counts of digests for various views on a Tile.
package tally

import (
	"fmt"
	"net/url"
	"sync"
	"time"

	"github.com/skia-dev/glog"
	"go.skia.org/infra/go/timer"
	"go.skia.org/infra/golden/go/storage"
	gtypes "go.skia.org/infra/golden/go/types"
	"go.skia.org/infra/perf/go/types"
)

type OnChangeCallback func()

// Tally maps a digest to a count.
type Tally map[string]int

// TraceTally maps each trace id to its Tally.
type TraceTally map[string]*Tally

// TestTally maps each test name to its Tally.
type TestTally map[string]*Tally

// Tallies allows querying for digest counts in different ways.
type Tallies struct {
	mutex      sync.Mutex
	storages   *storage.Storage
	traceTally TraceTally
	testTally  TestTally
	callbacks  []OnChangeCallback
}

// New creates a new Tallies for the given storage object.
func New(storages *storage.Storage) (*Tallies, error) {
	tile, err := storages.GetLastTileTrimmed(true)
	if err != nil {
		return nil, fmt.Errorf("Couldn't retrieve tile: %s", err)
	}

	trace, test := tallyTile(tile)
	t := &Tallies{
		traceTally: trace,
		testTally:  test,
		storages:   storages,
		callbacks:  []OnChangeCallback{},
	}
	go func() {
		for _ = range time.Tick(2 * time.Minute) {
			tile, err := storages.GetLastTileTrimmed(true)
			if err != nil {
				glog.Errorf("Couldn't retrieve tile: %s", err)
				continue
			}

			trace, test := tallyTile(tile)
			t.mutex.Lock()
			t.traceTally = trace
			t.testTally = test
			t.mutex.Unlock()
			for _, cb := range t.callbacks {
				go cb()
			}
		}
	}()
	return t, nil
}

func (t *Tallies) OnChange(f OnChangeCallback) {
	t.callbacks = append(t.callbacks, f)
}

func (t *Tallies) ByTest() TestTally {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	return t.testTally
}

func (t *Tallies) ByTrace() TraceTally {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	return t.traceTally
}

// ByQuery returns a Tally of all the digests that match the given query.
func (t *Tallies) ByQuery(query url.Values, includeIgnores bool) (Tally, error) {
	tile, err := t.storages.GetLastTileTrimmed(includeIgnores)
	if err != nil {
		return nil, fmt.Errorf("Couldn't retrieve tile: %s", err)
	}
	return tallyBy(tile, t.traceTally, query), nil

}

// tallyBy does the actual work of ByQuery.
func tallyBy(tile *types.Tile, traceTally TraceTally, query url.Values) Tally {
	ret := Tally{}
	for k, tr := range tile.Traces {
		if types.Matches(tr, query) {
			if _, ok := traceTally[k]; !ok {
				continue
			}
			for digest, n := range *traceTally[k] {
				if _, ok := ret[digest]; ok {
					ret[digest] += n
				} else {
					ret[digest] = n
				}
			}
		}
	}
	return ret
}

// tallyTile computes a TraceTally and TestTally from the given Tile.
func tallyTile(tile *types.Tile) (TraceTally, TestTally) {
	defer timer.New("tally").Stop()
	traceTally := TraceTally{}
	testTally := TestTally{}
	for k, tr := range tile.Traces {
		gtr := tr.(*types.GoldenTrace)
		tally := Tally{}
		for _, s := range gtr.Values {
			if s == types.MISSING_DIGEST {
				continue
			}
			if n, ok := tally[s]; ok {
				tally[s] = n + 1
			} else {
				tally[s] = 1
			}
		}
		traceTally[k] = &tally
		testName := tr.Params()[gtypes.PRIMARY_KEY_FIELD]
		if t, ok := testTally[testName]; ok {
			for digest, n := range tally {
				if _, ok := (*t)[digest]; ok {
					(*t)[digest] += n
				} else {
					(*t)[digest] = n
				}
			}
		} else {
			cp := Tally{}
			for k, v := range tally {
				cp[k] = v
			}
			testTally[testName] = &cp
		}
	}
	return traceTally, testTally
}
