// Copyright 2021 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 noder

import (
	"go/constant"

	"cmd/compile/internal/base"
	"cmd/compile/internal/syntax"
	"cmd/compile/internal/types"
	"cmd/compile/internal/types2"
)

// match reports whether types t1 and t2 are consistent
// representations for a given expression's type.
func (g *irgen) match(t1 *types.Type, t2 types2.Type, hasOK bool) bool {
	tuple, ok := t2.(*types2.Tuple)
	if !ok {
		// Not a tuple; can use simple type identity comparison.
		return types.Identical(t1, g.typ(t2))
	}

	if hasOK {
		// For has-ok values, types2 represents the expression's type as a
		// 2-element tuple, whereas ir just uses the first type and infers
		// that the second type is boolean. Must match either, since we
		// sometimes delay the transformation to the ir form.
		if tuple.Len() == 2 && types.Identical(t1, g.typ(tuple.At(0).Type())) {
			return true
		}
		return types.Identical(t1, g.typ(t2))
	}

	if t1 == nil || tuple == nil {
		return t1 == nil && tuple == nil
	}
	if !t1.IsFuncArgStruct() {
		return false
	}
	if t1.NumFields() != tuple.Len() {
		return false
	}
	for i, result := range t1.FieldSlice() {
		if !types.Identical(result.Type, g.typ(tuple.At(i).Type())) {
			return false
		}
	}
	return true
}

func (g *irgen) validate(n syntax.Node) {
	switch n := n.(type) {
	case *syntax.CallExpr:
		tv := g.info.Types[n.Fun]
		if tv.IsBuiltin() {
			fun := n.Fun
			for {
				builtin, ok := fun.(*syntax.ParenExpr)
				if !ok {
					break
				}
				fun = builtin.X
			}
			switch builtin := fun.(type) {
			case *syntax.Name:
				g.validateBuiltin(builtin.Value, n)
			case *syntax.SelectorExpr:
				g.validateBuiltin(builtin.Sel.Value, n)
			default:
				g.unhandled("builtin", n)
			}
		}
	}
}

func (g *irgen) validateBuiltin(name string, call *syntax.CallExpr) {
	switch name {
	case "Alignof", "Offsetof", "Sizeof":
		// Check that types2+gcSizes calculates sizes the same
		// as cmd/compile does.

		got, ok := constant.Int64Val(g.info.Types[call].Value)
		if !ok {
			base.FatalfAt(g.pos(call), "expected int64 constant value")
		}

		want := g.unsafeExpr(name, call.ArgList[0])
		if got != want {
			base.FatalfAt(g.pos(call), "got %v from types2, but want %v", got, want)
		}
	}
}

// unsafeExpr evaluates the given unsafe builtin function on arg.
func (g *irgen) unsafeExpr(name string, arg syntax.Expr) int64 {
	switch name {
	case "Alignof":
		return g.typ(g.info.Types[arg].Type).Alignment()
	case "Sizeof":
		return g.typ(g.info.Types[arg].Type).Size()
	}

	// Offsetof

	sel := arg.(*syntax.SelectorExpr)
	selection := g.info.Selections[sel]

	typ := g.typ(g.info.Types[sel.X].Type)
	typ = deref(typ)

	var offset int64
	for _, i := range selection.Index() {
		// Ensure field offsets have been calculated.
		types.CalcSize(typ)

		f := typ.Field(i)
		offset += f.Offset
		typ = f.Type
	}
	return offset
}
