// +build ignore

package main

// Test of maps with reflection.

import "reflect"

var a int
var b bool

func reflectMapKeysIndex() {
	m := make(map[*int]*bool) // @line mr1make
	m[&a] = &b

	mrv := reflect.ValueOf(m)
	print(mrv.Interface())                  // @types map[*int]*bool
	print(mrv.Interface().(map[*int]*bool)) // @pointsto makemap@mr1make:11
	print(mrv)                              // @pointsto makeinterface:map[*int]*bool
	print(mrv)                              // @types map[*int]*bool

	keys := mrv.MapKeys()
	print(keys) // @pointsto <alloc in (reflect.Value).MapKeys>
	for _, k := range keys {
		print(k)                    // @pointsto <alloc in (reflect.Value).MapKeys>
		print(k)                    // @types *int
		print(k.Interface())        // @types *int
		print(k.Interface().(*int)) // @pointsto main.a

		v := mrv.MapIndex(k)
		print(v.Interface())         // @types *bool
		print(v.Interface().(*bool)) // @pointsto main.b
	}
}

func reflectSetMapIndex() {
	m := make(map[*int]*bool)
	mrv := reflect.ValueOf(m)
	mrv.SetMapIndex(reflect.ValueOf(&a), reflect.ValueOf(&b))

	print(m[nil]) // @pointsto main.b

	for _, k := range mrv.MapKeys() {
		print(k.Interface())        // @types *int
		print(k.Interface().(*int)) // @pointsto main.a
	}

	tmap := reflect.TypeOf(m)
	// types.EvalNode won't let us refer to non-exported types:
	// print(tmap) // #@types *reflect.rtype
	print(tmap) // @pointsto map[*int]*bool

	zmap := reflect.Zero(tmap)
	print(zmap)             // @pointsto <alloc in reflect.Zero>
	print(zmap.Interface()) // @pointsto <alloc in reflect.Zero>

	print(tmap.Key())                            // @pointsto *int
	print(tmap.Elem())                           // @pointsto *bool
	print(reflect.Zero(tmap.Key()))              // @pointsto <alloc in reflect.Zero>
	print(reflect.Zero(tmap.Key()).Interface())  // @pointsto <alloc in reflect.Zero>
	print(reflect.Zero(tmap.Key()).Interface())  // @types *int
	print(reflect.Zero(tmap.Elem()))             // @pointsto <alloc in reflect.Zero>
	print(reflect.Zero(tmap.Elem()).Interface()) // @pointsto <alloc in reflect.Zero>
	print(reflect.Zero(tmap.Elem()).Interface()) // @types *bool
}

func reflectSetMapIndexInterface() {
	// Exercises reflect.Value conversions to/from interfaces:
	// a different code path than for concrete types.
	m := make(map[interface{}]interface{})
	reflect.ValueOf(m).SetMapIndex(reflect.ValueOf(&a), reflect.ValueOf(&b))
	for k, v := range m {
		print(k)         // @types *int
		print(k.(*int))  // @pointsto main.a
		print(v)         // @types *bool
		print(v.(*bool)) // @pointsto main.b
	}
}

func reflectSetMapIndexAssignable() {
	// SetMapIndex performs implicit assignability conversions.
	type I *int
	type J *int

	str := reflect.ValueOf("")

	// *int is assignable to I.
	m1 := make(map[string]I)
	reflect.ValueOf(m1).SetMapIndex(str, reflect.ValueOf(new(int))) // @line int
	print(m1[""])                                                   // @pointsto new@int:58

	// I is assignable to I.
	m2 := make(map[string]I)
	reflect.ValueOf(m2).SetMapIndex(str, reflect.ValueOf(I(new(int)))) // @line I
	print(m2[""])                                                      // @pointsto new@I:60

	// J is not assignable to I.
	m3 := make(map[string]I)
	reflect.ValueOf(m3).SetMapIndex(str, reflect.ValueOf(J(new(int))))
	print(m3[""]) // @pointsto
}

func reflectMakeMap() {
	t := reflect.TypeOf(map[*int]*bool(nil))
	v := reflect.MakeMap(t)
	print(v) // @types map[*int]*bool
	print(v) // @pointsto <alloc in reflect.MakeMap>
}

func main() {
	reflectMapKeysIndex()
	reflectSetMapIndex()
	reflectSetMapIndexInterface()
	reflectSetMapIndexAssignable()
	reflectMakeMap()
	// TODO(adonovan): reflect.MapOf(Type)
}
