//go:build go1.23

package mapsloop

import (
	"iter"
	"maps"
)

var _ = maps.Clone[M] // force "maps" import so that each diagnostic doesn't add one

type M map[int]string

// -- src is map --

func useCopy(dst, src map[int]string) {
	// Replace loop by maps.Copy.
	for key, value := range src {
		// A
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
	}
}

func useCopyRetrieveMap(x map[int]int) {
	getMap := func(int) map[int]int { return nil }
	for i, v := range x {
		// TODO(yuchen): don't assume that getMap returns the same map each time and has no effects.
		//
		// So, to avoid changing the cardinality of side effects,
		// the limit expression must not involve function calls (e.g. seq.Len()) or channel receives.
		getMap(0)[i] = v // want "Replace m\\[k\\]=v loop with maps.Copy"
	}
}

func useCopyGeneric[K comparable, V any, M ~map[K]V](dst, src M) {
	// Replace loop by maps.Copy.
	for key, value := range src {
		// A
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
	}
}

func useCopyNotClone(src map[int]string) {
	// Clone is tempting but wrong when src may be nil; see #71844.

	// Replace make(...) by maps.Copy.
	dst := make(map[int]string, len(src))
	// A
	for key, value := range src {
		// B
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
		// C
	}

	// A
	dst = map[int]string{}
	// B
	for key, value := range src {
		// C
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
	}
	println(dst)
}

func useCopyParen(src map[int]string) {
	// Clone is tempting but wrong when src may be nil; see #71844.

	// Replace (make)(...) by maps.Clone.
	dst := (make)(map[int]string, len(src))
	for key, value := range src {
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
	}

	dst = (map[int]string{})
	for key, value := range src {
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
	}
	println(dst)
}

func useCopy_typesDiffer(src M) {
	// Replace loop but not make(...) as maps.Copy(src) would return wrong type M.
	dst := make(map[int]string, len(src))
	for key, value := range src {
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
	}
	println(dst)
}

func useCopy_typesDiffer2(src map[int]string) {
	// Replace loop but not make(...) as maps.Copy(src) would return wrong type map[int]string.
	dst := make(M, len(src))
	for key, value := range src {
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
	}
	println(dst)
}

func useClone_typesDiffer3(src map[int]string) {
	// Clone is tempting but wrong when src may be nil; see #71844.

	// Replace loop and make(...) as maps.Clone(src) returns map[int]string
	// which is assignable to M.
	var dst M
	dst = make(M, len(src))
	for key, value := range src {
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
	}
	println(dst)
}

func useClone_typesDiffer4(src map[int]string) {
	// Clone is tempting but wrong when src may be nil; see #71844.

	// Replace loop and make(...) as maps.Clone(src) returns map[int]string
	// which is assignable to M.
	var dst M
	dst = make(M, len(src))
	for key, value := range src {
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
	}
	println(dst)
}

func useClone_generic[Map ~map[K]V, K comparable, V any](src Map) {
	// Clone is tempting but wrong when src may be nil; see #71844.

	// Replace loop and make(...) by maps.Clone
	dst := make(Map, len(src))
	for key, value := range src {
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Copy"
	}
	println(dst)
}

// -- src is iter.Seq2 --

func useInsert_assignableToSeq2(dst map[int]string, src func(yield func(int, string) bool)) {
	// Replace loop by maps.Insert because src is assignable to iter.Seq2.
	for k, v := range src {
		dst[k] = v // want "Replace m\\[k\\]=v loop with maps.Insert"
	}
}

func useCollect(src iter.Seq2[int, string]) {
	// Replace loop and make(...) by maps.Collect.
	var dst map[int]string
	dst = make(map[int]string) // A
	// B
	for key, value := range src {
		// C
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Collect"
	}
}

func useInsert_typesDifferAssign(src iter.Seq2[int, string]) {
	// Replace loop and make(...): maps.Collect returns an unnamed map type
	// that is assignable to M.
	var dst M
	dst = make(M)
	// A
	for key, value := range src {
		// B
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Collect"
	}
}

func useInsert_typesDifferDeclare(src iter.Seq2[int, string]) {
	// Replace loop but not make(...) as maps.Collect would return an
	// unnamed map type that would change the type of dst.
	dst := make(M)
	for key, value := range src {
		dst[key] = value // want "Replace m\\[k\\]=v loop with maps.Insert"
	}
}

// -- non-matches --

type isomerOfSeq2 func(yield func(int, string) bool)

func nopeInsertRequiresAssignableToSeq2(dst map[int]string, src isomerOfSeq2) {
	for k, v := range src { // nope: src is not assignable to maps.Insert's iter.Seq2 parameter
		dst[k] = v
	}
}

func nopeSingleVarRange(dst map[int]bool, src map[int]string) {
	for key := range src { // nope: must be "for k, v"
		dst[key] = true
	}
}

func nopeBodyNotASingleton(src map[int]string) {
	var dst map[int]string
	for key, value := range src {
		dst[key] = value
		println() // nope: other things in the loop body
	}
}

// Regression test for https://github.com/golang/go/issues/70815#issuecomment-2581999787.
func nopeAssignmentHasIncrementOperator(src map[int]int) {
	dst := make(map[int]int)
	for k, v := range src {
		dst[k] += v
	}
}

func nopeNotAMap(src map[int]string) {
	var dst []string
	for k, v := range src {
		dst[k] = v
	}
}

func nopeNotAMapGeneric[E any, M ~map[int]E, S ~[]E](src M) {
	var dst S
	for k, v := range src {
		dst[k] = v
	}
}

func nopeHasImplicitValueWidening(src map[string]int) {
	dst := make(map[string]any)
	for k, v := range src {
		dst[k] = v
	}
}

func nopeHasImplicitKeyWidening(src map[string]string) {
	dst := make(map[any]string)
	for k, v := range src {
		dst[k] = v
	}
}

// The expression for the map (y[v]) must not itself refer to loop variables.
// See https://go.dev/issue/77008.
func nopeMapExprUsesLoopVars(x map[int]int, y []map[int]int) {
	for i, v := range x {
		y[v][i] = v
	}
}

func nopeExtraKeyValueUsage(x map[int]int, y []map[int]int) {
	for i, v := range x {
		y[i][i] = v
	}

	getMap := func(int) map[int]int { return nil }
	for i, v := range x {
		getMap(i)[i] = v
	}

	for i, v := range x {
		getMap(v)[i] = v
	}
}

func nope2LhsAssigment(x map[int]int, y map[int]int) {
	for i, v := range x {
		y[i], _ = v, 0
	}
}
