// Copyright 2022 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 (
	"go/types"

	"golang.org/x/tools/internal/aliases"
	"golang.org/x/tools/internal/typeparams"
)

// Utilities for dealing with core types.

// isBytestring returns true if T has the same terms as interface{[]byte | string}.
// These act like a core type for some operations: slice expressions, append and copy.
//
// See https://go.dev/ref/spec#Core_types for the details on bytestring.
func isBytestring(T types.Type) bool {
	U := T.Underlying()
	if _, ok := U.(*types.Interface); !ok {
		return false
	}

	tset := typeSetOf(U)
	if tset.Len() != 2 {
		return false
	}
	hasBytes, hasString := false, false
	underIs(tset, func(t types.Type) bool {
		switch {
		case isString(t):
			hasString = true
		case isByteSlice(t):
			hasBytes = true
		}
		return hasBytes || hasString
	})
	return hasBytes && hasString
}

// termList is a list of types.
type termList []*types.Term            // type terms of the type set
func (s termList) Len() int            { return len(s) }
func (s termList) At(i int) types.Type { return s[i].Type() }

// typeSetOf returns the type set of typ. Returns an empty typeset on an error.
func typeSetOf(typ types.Type) termList {
	// This is a adaptation of x/exp/typeparams.NormalTerms which x/tools cannot depend on.
	var terms []*types.Term
	var err error
	// typeSetOf(t) == typeSetOf(Unalias(t))
	switch typ := aliases.Unalias(typ).(type) {
	case *types.TypeParam:
		terms, err = typeparams.StructuralTerms(typ)
	case *types.Union:
		terms, err = typeparams.UnionTermSet(typ)
	case *types.Interface:
		terms, err = typeparams.InterfaceTermSet(typ)
	default:
		// Common case.
		// Specializing the len=1 case to avoid a slice
		// had no measurable space/time benefit.
		terms = []*types.Term{types.NewTerm(false, typ)}
	}

	if err != nil {
		return termList(nil)
	}
	return termList(terms)
}

// underIs calls f with the underlying types of the specific type terms
// of s and reports whether all calls to f returned true. If there are
// no specific terms, underIs returns the result of f(nil).
func underIs(s termList, f func(types.Type) bool) bool {
	if s.Len() == 0 {
		return f(nil)
	}
	for i := 0; i < s.Len(); i++ {
		u := s.At(i).Underlying()
		if !f(u) {
			return false
		}
	}
	return true
}

// indexType returns the element type and index mode of a IndexExpr over a type.
// It returns (nil, invalid) if the type is not indexable; this should never occur in a well-typed program.
func indexType(typ types.Type) (types.Type, indexMode) {
	switch U := typ.Underlying().(type) {
	case *types.Array:
		return U.Elem(), ixArrVar
	case *types.Pointer:
		if arr, ok := U.Elem().Underlying().(*types.Array); ok {
			return arr.Elem(), ixVar
		}
	case *types.Slice:
		return U.Elem(), ixVar
	case *types.Map:
		return U.Elem(), ixMap
	case *types.Basic:
		return tByte, ixValue // must be a string
	case *types.Interface:
		tset := typeSetOf(U)
		if tset.Len() == 0 {
			return nil, ixInvalid // no underlying terms or error is empty.
		}

		elem, mode := indexType(tset.At(0))
		for i := 1; i < tset.Len() && mode != ixInvalid; i++ {
			e, m := indexType(tset.At(i))
			if !types.Identical(elem, e) { // if type checked, just a sanity check
				return nil, ixInvalid
			}
			// Update the mode to the most constrained address type.
			mode = mode.meet(m)
		}
		if mode != ixInvalid {
			return elem, mode
		}
	}
	return nil, ixInvalid
}

// An indexMode specifies the (addressing) mode of an index operand.
//
// Addressing mode of an index operation is based on the set of
// underlying types.
// Hasse diagram of the indexMode meet semi-lattice:
//
//	ixVar     ixMap
//	  |          |
//	ixArrVar     |
//	  |          |
//	ixValue      |
//	   \        /
//	  ixInvalid
type indexMode byte

const (
	ixInvalid indexMode = iota // index is invalid
	ixValue                    // index is a computed value (not addressable)
	ixArrVar                   // like ixVar, but index operand contains an array
	ixVar                      // index is an addressable variable
	ixMap                      // index is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
)

// meet is the address type that is constrained by both x and y.
func (x indexMode) meet(y indexMode) indexMode {
	if (x == ixMap || y == ixMap) && x != y {
		return ixInvalid
	}
	// Use int representation and return min.
	if x < y {
		return y
	}
	return x
}
