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

//go:build go1.22

package main

import (
	"reflect"
)

func main() {
	test_init()
	bound()
	manyvars()
	nocond()
	nopost()
	address_sequences()
	post_escapes()

	// Clones from cmd/compile/internal/loopvar/testdata .
	for_complicated_esc_address()
	for_esc_address()
	for_esc_closure()
	for_esc_method()
}

// After go1.22, each i will have a distinct address and value.
var distinct = func(m, n int) []*int {
	var r []*int
	for i := m; i <= n; i++ {
		r = append(r, &i)
	}
	return r
}(3, 5)

func test_init() {
	if len(distinct) != 3 {
		panic(distinct)
	}
	for i, v := range []int{3, 4, 5} {
		if v != *(distinct[i]) {
			panic(distinct)
		}
	}
}

func bound() {
	b := func(k int) func() int {
		var f func() int
		for i := 0; i < k; i++ {
			f = func() int { return i } // address before post updates i. So last value in the body.
		}
		return f
	}

	if got := b(0); got != nil {
		panic(got)
	}
	if got := b(5); got() != 4 {
		panic(got())
	}
}

func manyvars() {
	// Tests declaring many variables and having one in the middle escape.
	var f func() int
	for i, j, k, l, m, n, o, p := 7, 6, 5, 4, 3, 2, 1, 0; p < 6; l, p = l+1, p+1 {
		_, _, _, _, _, _, _, _ = i, j, k, l, m, n, o, p
		f = func() int { return l } // address *before* post updates l
	}
	if f() != 9 { // l == p+4
		panic(f())
	}
}

func nocond() {
	var c, b, e *int
	for p := 0; ; p++ {
		if p%7 == 0 {
			c = &p
			continue
		} else if p == 20 {
			b = &p
			break
		}
		e = &p
	}

	if *c != 14 {
		panic(c)
	}
	if *b != 20 {
		panic(b)
	}
	if *e != 19 {
		panic(e)
	}
}

func nopost() {
	var first, last *int
	for p := 0; p < 20; {
		if first == nil {
			first = &p
		}
		last = &p

		p++
	}

	if *first != 1 {
		panic(first)
	}
	if *last != 20 {
		panic(last)
	}
}

func address_sequences() {
	var c, b, p []*int

	cond := func(x *int) bool {
		c = append(c, x)
		return *x < 5
	}
	body := func(x *int) {
		b = append(b, x)
	}
	post := func(x *int) {
		p = append(p, x)
		(*x)++
	}
	for i := 0; cond(&i); post(&i) {
		body(&i)
	}

	if c[0] == c[1] {
		panic(c)
	}

	if !reflect.DeepEqual(c[:5], b) {
		panic(c)
	}

	if !reflect.DeepEqual(c[1:], p) {
		panic(c)
	}

	if !reflect.DeepEqual(b[1:], p[:4]) {
		panic(b)
	}
}

func post_escapes() {
	var p []*int
	post := func(x *int) {
		p = append(p, x)
		(*x)++
	}

	for i := 0; i < 5; post(&i) {
	}

	var got []int
	for _, x := range p {
		got = append(got, *x)
	}
	if want := []int{1, 2, 3, 4, 5}; !reflect.DeepEqual(got, want) {
		panic(got)
	}
}

func for_complicated_esc_address() {
	// Clone of for_complicated_esc_adress.go
	ss, sa := shared(23)
	ps, pa := private(23)
	es, ea := experiment(23)

	if ss != ps || ss != es || ea != pa || sa == pa {
		println("shared s, a", ss, sa, "; private, s, a", ps, pa, "; experiment s, a", es, ea)
		panic("for_complicated_esc_address")
	}
}

func experiment(x int) (int, int) {
	sum := 0
	var is []*int
	for i := x; i != 1; i = i / 2 {
		for j := 0; j < 10; j++ {
			if i == j { // 10 skips
				continue
			}
			sum++
		}
		i = i*3 + 1
		if i&1 == 0 {
			is = append(is, &i)
			for i&2 == 0 {
				i = i >> 1
			}
		} else {
			i = i + i
		}
	}

	asum := 0
	for _, pi := range is {
		asum += *pi
	}

	return sum, asum
}

func private(x int) (int, int) {
	sum := 0
	var is []*int
	I := x
	for ; I != 1; I = I / 2 {
		i := I
		for j := 0; j < 10; j++ {
			if i == j { // 10 skips
				I = i
				continue
			}
			sum++
		}
		i = i*3 + 1
		if i&1 == 0 {
			is = append(is, &i)
			for i&2 == 0 {
				i = i >> 1
			}
		} else {
			i = i + i
		}
		I = i
	}

	asum := 0
	for _, pi := range is {
		asum += *pi
	}

	return sum, asum
}

func shared(x int) (int, int) {
	sum := 0
	var is []*int
	i := x
	for ; i != 1; i = i / 2 {
		for j := 0; j < 10; j++ {
			if i == j { // 10 skips
				continue
			}
			sum++
		}
		i = i*3 + 1
		if i&1 == 0 {
			is = append(is, &i)
			for i&2 == 0 {
				i = i >> 1
			}
		} else {
			i = i + i
		}
	}

	asum := 0
	for _, pi := range is {
		asum += *pi
	}
	return sum, asum
}

func for_esc_address() {
	// Clone of for_esc_address.go
	sum := 0
	var is []*int
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			if i == j { // 10 skips
				continue
			}
			sum++
		}
		if i&1 == 0 {
			is = append(is, &i)
		}
	}

	bug := false
	if sum != 100-10 {
		println("wrong sum, expected", 90, ", saw", sum)
		bug = true
	}
	if len(is) != 5 {
		println("wrong iterations, expected ", 5, ", saw", len(is))
		bug = true
	}
	sum = 0
	for _, pi := range is {
		sum += *pi
	}
	if sum != 0+2+4+6+8 {
		println("wrong sum, expected ", 20, ", saw ", sum)
		bug = true
	}
	if bug {
		panic("for_esc_address")
	}
}

func for_esc_closure() {
	var is []func() int

	// Clone of for_esc_closure.go
	sum := 0
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			if i == j { // 10 skips
				continue
			}
			sum++
		}
		if i&1 == 0 {
			is = append(is, func() int {
				if i%17 == 15 {
					i++
				}
				return i
			})
		}
	}

	bug := false
	if sum != 100-10 {
		println("wrong sum, expected ", 90, ", saw", sum)
		bug = true
	}
	if len(is) != 5 {
		println("wrong iterations, expected ", 5, ", saw", len(is))
		bug = true
	}
	sum = 0
	for _, f := range is {
		sum += f()
	}
	if sum != 0+2+4+6+8 {
		println("wrong sum, expected ", 20, ", saw ", sum)
		bug = true
	}
	if bug {
		panic("for_esc_closure")
	}
}

type I int

func (x *I) method() int {
	return int(*x)
}

func for_esc_method() {
	// Clone of for_esc_method.go
	var is []func() int
	sum := 0
	for i := I(0); int(i) < 10; i++ {
		for j := 0; j < 10; j++ {
			if int(i) == j { // 10 skips
				continue
			}
			sum++
		}
		if i&1 == 0 {
			is = append(is, i.method)
		}
	}

	bug := false
	if sum != 100-10 {
		println("wrong sum, expected ", 90, ", saw ", sum)
		bug = true
	}
	if len(is) != 5 {
		println("wrong iterations, expected ", 5, ", saw", len(is))
		bug = true
	}
	sum = 0
	for _, m := range is {
		sum += m()
	}
	if sum != 0+2+4+6+8 {
		println("wrong sum, expected ", 20, ", saw ", sum)
		bug = true
	}
	if bug {
		panic("for_esc_method")
	}
}
