// 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 ifaceassert

import (
	"go/types"

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

// isParameterized reports whether typ contains any of the type parameters of tparams.
//
// NOTE: Adapted from go/types/infer.go. If that is exported in a future release remove this copy.
func isParameterized(typ types.Type) bool {
	w := tpWalker{
		seen: make(map[types.Type]bool),
	}
	return w.isParameterized(typ)
}

type tpWalker struct {
	seen map[types.Type]bool
}

func (w *tpWalker) isParameterized(typ types.Type) (res bool) {
	// detect cycles
	if x, ok := w.seen[typ]; ok {
		return x
	}
	w.seen[typ] = false
	defer func() {
		w.seen[typ] = res
	}()

	switch t := typ.(type) {
	case nil, *types.Basic: // TODO(gri) should nil be handled here?
		break

	case *types.Array:
		return w.isParameterized(t.Elem())

	case *types.Slice:
		return w.isParameterized(t.Elem())

	case *types.Struct:
		for i, n := 0, t.NumFields(); i < n; i++ {
			if w.isParameterized(t.Field(i).Type()) {
				return true
			}
		}

	case *types.Pointer:
		return w.isParameterized(t.Elem())

	case *types.Tuple:
		n := t.Len()
		for i := 0; i < n; i++ {
			if w.isParameterized(t.At(i).Type()) {
				return true
			}
		}

	case *types.Signature:
		// t.tparams may not be nil if we are looking at a signature
		// of a generic function type (or an interface method) that is
		// part of the type we're testing. We don't care about these type
		// parameters.
		// Similarly, the receiver of a method may declare (rather than
		// use) type parameters, we don't care about those either.
		// Thus, we only need to look at the input and result parameters.
		return w.isParameterized(t.Params()) || w.isParameterized(t.Results())

	case *types.Interface:
		for i, n := 0, t.NumMethods(); i < n; i++ {
			if w.isParameterized(t.Method(i).Type()) {
				return true
			}
		}
		terms, err := typeparams.InterfaceTermSet(t)
		if err != nil {
			panic(err)
		}
		for _, term := range terms {
			if w.isParameterized(term.Type()) {
				return true
			}
		}

	case *types.Map:
		return w.isParameterized(t.Key()) || w.isParameterized(t.Elem())

	case *types.Chan:
		return w.isParameterized(t.Elem())

	case *types.Named:
		list := typeparams.NamedTypeArgs(t)
		for i, n := 0, list.Len(); i < n; i++ {
			if w.isParameterized(list.At(i)) {
				return true
			}
		}

	case *typeparams.TypeParam:
		return true

	default:
		panic(t) // unreachable
	}

	return false
}
