// Copyright 2026 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.

package ssa

import (
	"fmt"
	"iter"
	"slices"
	"testing"

	"cmd/compile/internal/ssa/block"
)

// genCrossLadder builds a k-column, 2-rail cross ladder CFG:
//
//	entry → L1  R1
//	        │╲ ╱│     every block branches to BOTH blocks of
//	        │ ╳ │     the next column
//	        │╱ ╲│
//	        L2  R2
//	         ...
//	        Lk  Rk
//	         ↘  ↙
//	         exit
//
// The cross edges help to do quadratic DF+ walks (assume each of N blocks has another def
// and needs to iterate with f.IterDomFrontierPlus O(N) blocks).
// Returned are the function and its column blocks, column by column.
func genCrossLadder(k int) (*Func, []*Block) {
	f := (&Config{}).NewFunc(nil, &Cache{})
	entry := f.NewBlock(block.BlockIf)
	f.Entry = entry
	exit := f.NewBlock(block.BlockExit)
	col := make([]*Block, 0, 2*k)
	prevL, prevR := entry, entry
	for i := 0; i < k; i++ {
		kind := block.BlockIf
		if i == k-1 {
			kind = block.BlockPlain // goto exit
		}
		l := f.NewBlock(kind)
		r := f.NewBlock(kind)
		col = append(col, l, r)
		prevL.AddEdgeTo(l)
		prevL.AddEdgeTo(r)
		prevR.AddEdgeTo(l)
		prevR.AddEdgeTo(r)
		prevL, prevR = l, r
	}
	col[len(col)-2].AddEdgeTo(exit)
	col[len(col)-1].AddEdgeTo(exit)
	return f, col
}

// BenchmarkIterDomFrontierPlus walks the iterated dominance frontier of every
// column block of a cross ladder, the merge-set stress shape.
// Ideally, ns/block (ns/op ÷ blocks/op) stays flat as k grows.
func BenchmarkIterDomFrontierPlus(b *testing.B) {
	for _, k := range []int{8, 16, 32} {
		b.Run(fmt.Sprintf("k=%d", k), func(b *testing.B) {
			f, col := genCrossLadder(k)
			b.ReportAllocs()
			b.ResetTimer()
			var n int
			for i := 0; i < b.N; i++ {
				for j := range col {
					for range f.IterDomFrontierPlus(slices.Values(col[j : j+1])) {
						n++
					}
				}
			}
			b.StopTimer()
			b.ReportMetric(float64(n)/float64(b.N), "blocks/op")
			if n != 2*k*k*b.N {
				b.Fatalf("walked %d blocks per round, want %d", n/b.N, 2*k*k)
			}
		})
	}
}

// TestIterDomFrontierPlusSeedAtMerge tests DF+ of a small CFG with a loop
// where its header is both a seed and a merge point.
// A def in an unreachable block (u → b3) must not join the merge set,
// and the header (b2) must be in it.
func TestIterDomFrontierPlusSeedAtMerge(t *testing.T) {
	//
	//	x := 0
	// loop:
	//	x = x + 1         // b2: def in the loop head
	//	if c { continue } // b4 → b2, back edge 1
	//	if d { break }    // b5 → b3
	//	goto loop         // b5 → b2, back edge 2
	//	return x          // b3
	// unreachable: x = 9; // u → b3
	//
	f := (&Config{}).NewFunc(nil, &Cache{})
	b1 := f.NewBlock(block.BlockPlain) // entry: x:=0
	f.Entry = b1
	b2 := f.NewBlock(block.BlockIf)    // loop head: x = x + 1; if c
	b4 := f.NewBlock(block.BlockPlain) // { continue }
	b5 := f.NewBlock(block.BlockIf)    // if d { break }; goto loop
	b3 := f.NewBlock(block.BlockExit)
	u := f.NewBlock(block.BlockPlain) // unreachable; goto b3

	b1.AddEdgeTo(b2)
	b2.AddEdgeTo(b4)
	b2.AddEdgeTo(b5)
	b4.AddEdgeTo(b2) // back edge 1
	b5.AddEdgeTo(b3) // break
	b5.AddEdgeTo(b2) // back edge 2
	u.AddEdgeTo(b3)  // goto b3

	got := collectBlockIDs(f.IterDomFrontierPlus(slices.Values([]*Block{b1, b2, u})))
	if want := []ID{b2.ID}; !slices.Equal(got, want) {
		t.Errorf("got DF+ = %v, want %v", got, want)
	}
}

func TestIterDomFrontierPlusOrigin(t *testing.T) {
	f := (&Config{}).NewFunc(nil, &Cache{})
	entry := f.NewBlock(block.BlockIf)
	f.Entry = entry
	left := f.NewBlock(block.BlockPlain)
	right := f.NewBlock(block.BlockPlain)
	merge := f.NewBlock(block.BlockExit)

	entry.AddEdgeTo(left)
	entry.AddEdgeTo(right)
	left.AddEdgeTo(merge)
	right.AddEdgeTo(merge)

	var got [][2]*Block
	for b, origin := range f.IterDomFrontierPlus(slices.Values([]*Block{left})) {
		got = append(got, [2]*Block{b, origin})
	}
	if want := [][2]*Block{{merge, left}}; !slices.Equal(got, want) {
		t.Fatalf("got frontier and origin %v, want %v", got, want)
	}
}

func collectBlockIDs(seq iter.Seq2[*Block, *Block]) []ID {
	var ids []ID
	for b := range seq {
		ids = append(ids, b.ID)
	}
	return ids
}
