// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package vdltest

import (
	"fmt"
	"hash"
	"hash/fnv"
	"math/rand"
	"strconv"
	"time"

	"v.io/v23/vdl"
)

// IsCanonical returns true iff e.Target == e.Source.
func (e EntryValue) IsCanonical() bool {
	return vdl.EqualValue(e.Target, e.Source)
}

// EntryGenerator generates test entries.
type EntryGenerator struct {
	// AllMaxMinTargets specifies that all max/min targets should be generated.
	// By default max/min targets are only generated for numbers.
	AllMaxMinTargets bool
	// RandomTargetLimit limits the number of random targets that are generated.
	RandomTargetLimit int
	// Each of the *Entries fields configures, for each unique target, the
	// number of non-canonical entries with the given label that are generated.
	ZeroEntryLimit   int
	MaxMinEntryLimit int
	FullEntryLimit   int
	RandomEntryLimit int

	valueGen *ValueGenerator
	hasher   hash.Hash64
	randSeed int64
	rng      *rand.Rand
	// Keep the total set of types separated by kind, for quick filtering.
	ttBool, ttStringEnum, ttNumber, ttArrayList, ttSet, ttMap, ttStruct, ttUnion []*vdl.Type
}

// NewEntryGenerator returns a new EntryGenerator, which uses a random number
// generator seeded to the current time.  The sourceTypes specify the types to
// consider when creating source values for each entry.
func NewEntryGenerator(sourceTypes []*vdl.Type) *EntryGenerator {
	now := time.Now().Unix()
	g := &EntryGenerator{
		RandomTargetLimit: 1,
		ZeroEntryLimit:    2,
		MaxMinEntryLimit:  2,
		FullEntryLimit:    1,
		RandomEntryLimit:  1,
		valueGen:          NewValueGenerator(sourceTypes),
		hasher:            fnv.New64a(),
		randSeed:          now,
		rng:               rand.New(rand.NewSource(now)),
	}
	for _, tt := range sourceTypes {
		kind := tt.NonOptional().Kind()
		if kind.IsNumber() {
			g.ttNumber = append(g.ttNumber, tt)
		}
		switch kind {
		case vdl.Bool:
			g.ttBool = append(g.ttBool, tt)
		case vdl.String, vdl.Enum:
			g.ttStringEnum = append(g.ttStringEnum, tt)
		case vdl.Array, vdl.List:
			g.ttArrayList = append(g.ttArrayList, tt)
		case vdl.Set:
			g.ttSet = append(g.ttSet, tt)
		case vdl.Map:
			g.ttMap = append(g.ttMap, tt)
		case vdl.Struct:
			g.ttStruct = append(g.ttStruct, tt)
		case vdl.Union:
			g.ttUnion = append(g.ttUnion, tt)
		}
	}
	return g
}

// RandSeed sets the seed for the random number generator used by g.
func (g *EntryGenerator) RandSeed(seed int64) {
	g.randSeed = seed
}

// candidateTypes returns the types whose values might be convertible to values
// of the tt type.  In theory we could run a compatibility check here for fewer
// false positives, but we'll need to check compatibility again when generating
// values anyways, to handle inner types of nested any, so we don't bother.
func (g *EntryGenerator) candidateTypes(tt *vdl.Type, mode sourceMode) []*vdl.Type {
	var candidates []*vdl.Type
	kind := tt.NonOptional().Kind()
	if kind.IsNumber() {
		candidates = g.ttNumber
	}
	switch kind {
	case vdl.Bool:
		candidates = g.ttBool
	case vdl.String, vdl.Enum:
		candidates = g.ttStringEnum
	case vdl.Array, vdl.List:
		candidates = g.ttArrayList
	case vdl.Set:
		candidates = g.ttSet
	case vdl.Map:
		candidates = g.ttMap
	case vdl.Struct:
		candidates = g.ttStruct
	case vdl.Union:
		candidates = g.ttUnion
	case vdl.TypeObject:
		candidates = []*vdl.Type{vdl.TypeObjectType}
	}
	if mode == sourceAll {
		return candidates
	}
	var filtered []*vdl.Type
	for _, c := range candidates {
		if mode.Unnamed() && c.Name() == "" || mode.Named() && c.Name() != "" {
			filtered = append(filtered, c)
		}
	}
	return filtered
}

// GenAllPass generates a list of passing entries for all targetTypes.
func (g *EntryGenerator) GenAllPass(targetTypes []*vdl.Type) []EntryValue {
	var entries []EntryValue
	for _, tt := range targetTypes {
		entries = append(entries, g.GenPass(tt)...)
	}
	return entries
}

// GenPass generates a list of passing entries for the tt type.  Each entry has
// a target value of type tt.  The source value of each entry is created with
// the property that, if the source value is converted to the target type, the
// result is exactly the target value.
func (g *EntryGenerator) GenPass(tt *vdl.Type) []EntryValue {
	// Add entries for zero values.
	ev := g.genPass("Zero", vdl.ZeroValue(tt), g.ZeroEntryLimit, sourceAll)
	if tt.Kind() == vdl.Optional {
		// Add entry to convert from any(nil) to optional(nil).
		ev = append(ev, EntryValue{
			Label:  "NilAny",
			Target: vdl.ZeroValue(tt),
			Source: vdl.ZeroValue(vdl.AnyType),
		})
	}
	// Handle some special-cases.
	switch {
	case tt == vdl.AnyType:
		// Don't create non-nil any values.
		return ev
	case tt.Kind() == vdl.Enum:
		// Test all enum values exhaustively.
		for ix := 1; ix < tt.NumEnumLabel(); ix++ {
			ev = append(ev, g.genPass("Full", vdl.EnumValue(tt, ix), -1, sourceAll)...)
		}
		return ev
	}
	// Add entries for max/min number testing.
	if needsGenPos(tt) && (g.AllMaxMinTargets || tt.Kind().IsNumber()) {
		max := g.makeValue(tt, "+Max", GenPosMax)
		min := g.makeValue(tt, "+Min", GenPosMin)
		ev = append(ev, g.genPassMaxMin("+Max", max)...)
		ev = append(ev, g.genPassMaxMin("+Min", min)...)
	}
	if needsGenNeg(tt) && (g.AllMaxMinTargets || tt.Kind().IsNumber()) {
		max := g.makeValue(tt, "-Max", GenNegMax)
		min := g.makeValue(tt, "-Min", GenNegMin)
		ev = append(ev, g.genPassMaxMin("-Max", max)...)
		ev = append(ev, g.genPassMaxMin("-Min", min)...)
	}
	// Add full entries, which are deterministic and recursively non-zero.  As a
	// special-case, for types that are part of a cycle, the values are still
	// deterministic but will contain zero items.
	if needsGenFull(tt) {
		full := g.makeValue(tt, "Full", GenFull)
		ev = append(ev, g.genPass("Full", full, g.FullEntryLimit, sourceAll)...)
	}
	// Add some random entries.
	if needsGenRandom(tt) {
		for ix := 0; ix < g.RandomTargetLimit; ix++ {
			label := "Random" + strconv.Itoa(ix)
			random := g.makeValue(tt, label, GenRandom)
			ev = append(ev, g.genPass(label, random, g.RandomEntryLimit, sourceAll)...)
		}
	}
	return ev
}

func (g *EntryGenerator) genPassMaxMin(label string, target *vdl.Value) []EntryValue {
	var ev []EntryValue
	switch ttTarget := target.Type(); {
	case ttTarget.Kind().IsNumber():
		// We test the boundaries of all unnamed (i.e. built-in) numbers with other
		// unnamed numbers, and test the boundaries of all named numbers with other
		// named numbers.  We limit the entries otherwise.
		if ttTarget.Name() == "" {
			ev = append(ev, g.genPass(label, target, -1, sourceUnnamed)...)
			ev = append(ev, g.genPass(label, target, g.MaxMinEntryLimit, sourceNamedNoCanonical)...)
		} else {
			ev = append(ev, g.genPass(label, target, -1, sourceNamed)...)
			ev = append(ev, g.genPass(label, target, g.MaxMinEntryLimit, sourceUnnamedNoCanonical)...)
		}
	default:
		ev = append(ev, g.genPass(label, target, g.MaxMinEntryLimit, sourceAll)...)
	}
	return ev
}

type sourceMode int

const (
	sourceAll                sourceMode = iota // Consider all source types.
	sourceUnnamed                              // Only unnamed types.
	sourceUnnamedNoCanonical                   // Only unnamed types, no canonical.
	sourceNamed                                // Only named types.
	sourceNamedNoCanonical                     // Only named types, no canonical.
)

func (m sourceMode) String() string {
	switch m {
	case sourceAll:
		return "All"
	case sourceUnnamed:
		return "Unnamed"
	case sourceUnnamedNoCanonical:
		return "UnnamedNoCanonical"
	case sourceNamed:
		return "Named"
	case sourceNamedNoCanonical:
		return "NamedNoCanonical"
	}
	panic(fmt.Errorf("vdltest: unhandled mode %d", m))
}

func (m sourceMode) Canonical() bool {
	return m == sourceAll || m == sourceUnnamed || m == sourceNamed
}

func (m sourceMode) Unnamed() bool {
	return m == sourceAll || m == sourceUnnamed || m == sourceUnnamedNoCanonical
}

func (m sourceMode) Named() bool {
	return m == sourceAll || m == sourceNamed || m == sourceNamedNoCanonical
}

// genPass generates a list of passing entries, where each entry has the given
// target value.  The given limit restricts the number of returned entries to
// that value; -1 returns all entries.
func (g *EntryGenerator) genPass(label string, target *vdl.Value, limit int, mode sourceMode) []EntryValue {
	var ev []EntryValue
	if mode.Canonical() {
		// Add the canonical identity conversion for each target value.
		ev = append(ev, EntryValue{
			Label:  label,
			Target: target,
			Source: target,
		})
	}
	// Add up to limit conversion entries.  The strategy is to add an entry for
	// each source type where we can create a value that can convert to the
	// target.  We filter out all types that cannot possibly be convertible, and
	// are left with candidates.  The candidates still might not be convertible,
	// so we try to mimic values for each type, and add the entry if it succeeds.
	candidates := g.candidateTypes(target.Type(), mode)
	switch {
	case limit == 0:
		candidates = nil
	case limit != -1:
		// Randomly permute the candidates if we're returning a limited number of
		// entries, to cover more cases.
		shuffled := make([]*vdl.Type, len(candidates))
		for i, p := range g.perm(len(candidates), target.Type(), label, mode) {
			shuffled[i] = candidates[p]
		}
		candidates = shuffled
	}
	num := 0
	for _, ttSource := range candidates {
		if ttSource == target.Type() {
			continue // Skip the canonical case, which was handled above.
		}
		if source := MimicValue(ttSource, target); source != nil {
			if limit > -1 && num >= limit {
				break
			}
			num++
			ev = append(ev, EntryValue{
				Label:  label,
				Target: target,
				Source: source,
			})
		}
	}
	return ev
}

func (g *EntryGenerator) makeValue(tt *vdl.Type, label string, mode GenMode) *vdl.Value {
	// ValueGenerator creates random values for us, but we'd like to ensure that
	// the values don't change spuriously.  I.e. adding new types or generating
	// more values shouldn't change any existing values.  To this end, we seed the
	// random source with a hash of the unique type string, gen mode and iteration
	// counter i.
	g.hasher.Reset()
	g.hasher.Write([]byte(tt.Unique()))
	g.hasher.Write([]byte(label))
	g.hasher.Write([]byte(mode.String()))
	g.valueGen.RandSeed(g.randSeed + int64(g.hasher.Sum64()))
	return g.valueGen.Gen(tt, mode)
}

func (g *EntryGenerator) perm(n int, tt *vdl.Type, label string, mode sourceMode) []int {
	// Similar to makeValue, we'd like to ensure that our choice of random
	// candidate permutations don't change our test values spuriously.
	g.hasher.Reset()
	g.hasher.Write([]byte(tt.Unique()))
	g.hasher.Write([]byte(label))
	g.hasher.Write([]byte(mode.String()))
	g.rng.Seed(g.randSeed + int64(g.hasher.Sum64()))
	return g.rng.Perm(n)
}

// GenAllFail generates a list of failing entries for all targetTypes.
func (g *EntryGenerator) GenAllFail(targetTypes []*vdl.Type) []EntryValue {
	var entries []EntryValue
	for _, tt := range targetTypes {
		entries = append(entries, g.GenFail(tt)...)
	}
	return entries
}

// GenFail generates a list of failing entries for the tt type.  Each entry has
// a target value of type tt.  The source value of each entry is created with
// the property that, if the source value is converted to the target type, the
// conversion fails.
func (g *EntryGenerator) GenFail(tt *vdl.Type) []EntryValue {
	// TODO(toddw): Implement this!
	return nil
}
