// Copyright 2020 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 test

// This file contains utility routines and harness infrastructure used
// by the ABI tests in "abiutils_test.go".

import (
	"cmd/compile/internal/abi"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/typecheck"
	"cmd/compile/internal/types"
	"cmd/internal/src"
	"fmt"
	"strings"
	"testing"
	"text/scanner"
)

func mkParamResultField(t *types.Type, s *types.Sym, which ir.Class) *types.Field {
	field := types.NewField(src.NoXPos, s, t)
	n := typecheck.NewName(s)
	n.Class = which
	field.Nname = n
	n.SetType(t)
	return field
}

// mkstruct is a helper routine to create a struct type with fields
// of the types specified in 'fieldtypes'.
func mkstruct(fieldtypes []*types.Type) *types.Type {
	fields := make([]*types.Field, len(fieldtypes))
	for k, t := range fieldtypes {
		if t == nil {
			panic("bad -- field has no type")
		}
		f := types.NewField(src.NoXPos, nil, t)
		fields[k] = f
	}
	s := types.NewStruct(types.LocalPkg, fields)
	return s
}

func mkFuncType(rcvr *types.Type, ins []*types.Type, outs []*types.Type) *types.Type {
	q := typecheck.Lookup("?")
	inf := []*types.Field{}
	for _, it := range ins {
		inf = append(inf, mkParamResultField(it, q, ir.PPARAM))
	}
	outf := []*types.Field{}
	for _, ot := range outs {
		outf = append(outf, mkParamResultField(ot, q, ir.PPARAMOUT))
	}
	var rf *types.Field
	if rcvr != nil {
		rf = mkParamResultField(rcvr, q, ir.PPARAM)
	}
	return types.NewSignature(types.LocalPkg, rf, nil, inf, outf)
}

type expectedDump struct {
	dump string
	file string
	line int
}

func tokenize(src string) []string {
	var s scanner.Scanner
	s.Init(strings.NewReader(src))
	res := []string{}
	for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
		res = append(res, s.TokenText())
	}
	return res
}

func verifyParamResultOffset(t *testing.T, f *types.Field, r abi.ABIParamAssignment, which string, idx int) int {
	n := ir.AsNode(f.Nname).(*ir.Name)
	if n.FrameOffset() != int64(r.Offset()) {
		t.Errorf("%s %d: got offset %d wanted %d t=%v",
			which, idx, r.Offset(), n.Offset_, f.Type)
		return 1
	}
	return 0
}

func makeExpectedDump(e string) expectedDump {
	return expectedDump{dump: e}
}

func difftokens(atoks []string, etoks []string) string {
	if len(atoks) != len(etoks) {
		return fmt.Sprintf("expected %d tokens got %d",
			len(etoks), len(atoks))
	}
	for i := 0; i < len(etoks); i++ {
		if etoks[i] == atoks[i] {
			continue
		}

		return fmt.Sprintf("diff at token %d: expected %q got %q",
			i, etoks[i], atoks[i])
	}
	return ""
}

func nrtest(t *testing.T, ft *types.Type, expected int) {
	types.CalcSize(ft)
	got := configAMD64.NumParamRegs(ft)
	if got != expected {
		t.Errorf("]\nexpected num regs = %d, got %d, type %v", expected, got, ft)
	}
}

func abitest(t *testing.T, ft *types.Type, exp expectedDump) {

	types.CalcSize(ft)

	// Analyze with full set of registers.
	regRes := configAMD64.ABIAnalyze(ft)
	regResString := strings.TrimSpace(regRes.String())

	// Check results.
	reason := difftokens(tokenize(regResString), tokenize(exp.dump))
	if reason != "" {
		t.Errorf("\nexpected:\n%s\ngot:\n%s\nreason: %s",
			strings.TrimSpace(exp.dump), regResString, reason)
	}

	// Analyze again with empty register set.
	empty := abi.NewABIConfig(0, 0)
	emptyRes := empty.ABIAnalyze(ft)
	emptyResString := emptyRes.String()

	// Walk the results and make sure the offsets assigned match
	// up with those assiged by CalcSize. This checks to make sure that
	// when we have no available registers the ABI assignment degenerates
	// back to the original ABI0.

	// receiver
	failed := 0
	rfsl := ft.Recvs().Fields().Slice()
	poff := 0
	if len(rfsl) != 0 {
		failed |= verifyParamResultOffset(t, rfsl[0], emptyRes.InParams()[0], "receiver", 0)
		poff = 1
	}
	// params
	pfsl := ft.Params().Fields().Slice()
	for k, f := range pfsl {
		verifyParamResultOffset(t, f, emptyRes.InParams()[k+poff], "param", k)
	}
	// results
	ofsl := ft.Results().Fields().Slice()
	for k, f := range ofsl {
		failed |= verifyParamResultOffset(t, f, emptyRes.OutParams()[k], "result", k)
	}

	if failed != 0 {
		t.Logf("emptyres:\n%s\n", emptyResString)
	}
}
