// Copyright 2018 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 darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris

package gocore

import (
	"fmt"
	"testing"
)

func checkDominator(t *testing.T, d ltDom) bool {
	t.Helper()
	// Build pointer-y graph.
	pRoot := sanityVertex{}
	roots := make([]sanityVertex, d.nRoots)
	objects := make([]sanityVertex, d.p.nObj)

	for i, r := range d.p.rootIdx {
		v := &roots[i]
		v.root = r
		pRoot.succ = append(pRoot.succ, v)
		v.pred = append(v.pred, &pRoot)
		d.p.ForEachRootPtr(r, func(_ int64, x Object, _ int64) bool {
			idx, _ := d.p.findObjectIndex(d.p.Addr(x))
			v.succ = append(v.succ, &objects[idx])
			objects[idx].pred = append(objects[idx].pred, v)
			return true
		})
	}
	d.p.ForEachObject(func(x Object) bool {
		xIdx, _ := d.p.findObjectIndex(d.p.Addr(x))
		v := &objects[xIdx]
		v.obj = x
		d.p.ForEachPtr(x, func(_ int64, y Object, _ int64) bool {
			yIdx, _ := d.p.findObjectIndex(d.p.Addr(y))
			v.succ = append(v.succ, &objects[yIdx])
			objects[yIdx].pred = append(objects[yIdx].pred, v)
			return true
		})
		return true
	})

	// Precompute postorder traversal.
	var postorder []*sanityVertex
	type workItem struct {
		v    *sanityVertex
		mode dfsMode
	}
	seen := make(map[*sanityVertex]bool, d.nVertices)
	work := []workItem{{&pRoot, down}}
	for len(work) > 0 {
		item := &work[len(work)-1]

		if item.mode == down && len(item.v.succ) != 0 {
			item.mode = up
			for _, w := range item.v.succ {
				// Only push each node once.
				if seen[w] {
					continue
				}
				seen[w] = true

				work = append(work, workItem{w, down})
			}
			continue
		}

		work = work[:len(work)-1]
		postorder = append(postorder, item.v)
	}

	// Make map from block id to order index (for intersect call)
	postnum := make(map[*sanityVertex]int, d.nVertices)
	for i, b := range postorder {
		postnum[b] = i
	}

	// Make the pseudo-root a self-loop
	pRoot.idom = &pRoot
	if postnum[&pRoot] != len(postorder)-1 {
		panic("pseudo-root not last in postorder")
	}

	// Compute relaxation of idom entries
	for {
		changed := false

		for i := len(postorder) - 2; i >= 0; i-- {
			v := postorder[i]
			var d *sanityVertex

			for _, pred := range v.pred {
				if pred.idom == nil {
					continue
				}

				if d == nil {
					d = pred
					continue
				}

				d = intersect(d, pred, postnum)
			}
			if v.idom != d {
				v.idom = d
				changed = true
			}
		}

		if !changed {
			break
		}
	}

	pRoot.idom = nil

	getVertex := func(n vName) *sanityVertex {
		r, o := d.findVertexByName(n)
		switch {
		case n == pseudoRoot:
			return &pRoot
		case r != nil:
			return &roots[r.id]
		default:
			idx, _ := d.p.findObjectIndex(d.p.Addr(o))
			return &objects[idx]
		}
	}

	matches := true
	for vertName, domName := range d.idom {
		if vName(vertName) == pseudoRoot {
			continue
		}
		vert := getVertex(vName(vertName))
		dom := getVertex(domName)

		if vert.idom != dom {
			matches = false
			t.Errorf("Mismatch in idom for %v, name #%04v: fast reports %v, sanity reports %v\n", vert.String(d.p), vertName, dom.String(d.p), vert.idom.String(d.p))
		}
	}
	return matches
}

func intersect(v, w *sanityVertex, postnum map[*sanityVertex]int) *sanityVertex {
	for v != w {
		if postnum[v] < postnum[w] {
			v = v.idom
		} else {
			w = w.idom
		}
	}
	return v
}

type sanityVertex struct {
	root *Root
	obj  Object
	pred []*sanityVertex
	succ []*sanityVertex
	idom *sanityVertex
}

func (v *sanityVertex) String(p *Process) string {
	switch {
	case v.root != nil:
		return fmt.Sprintf("root %s (type %s)", v.root.Name, v.root.Type)
	case v.obj != 0:
		typ, _ := p.Type(v.obj)
		var typeName string
		if typ != nil {
			typeName = typ.Name
		}
		return fmt.Sprintf("object %#x (type %s)", v.obj, typeName)
	default:
		return "pseudo-root"
	}
}
