// 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"
	"sync"

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

// tpWalker walks over types looking for parameterized types.
//
// NOTE: Adapted from go/types/infer.go. If that is exported in a future release remove this copy.
type tpWalker struct {
	mu   sync.Mutex
	seen map[types.Type]bool
}

// isParameterized reports whether t recursively contains a type parameter.
// Thread-safe.
func (w *tpWalker) isParameterized(t types.Type) bool {
	// TODO(adonovan): profile. If this operation is expensive,
	// handle the most common but shallow cases such as T, pkg.T,
	// *T without consulting the cache under the lock.

	w.mu.Lock()
	defer w.mu.Unlock()
	return w.isParameterizedLocked(t)
}

// Requires w.mu.
func (w *tpWalker) isParameterizedLocked(typ types.Type) (res bool) {
	// NOTE: Adapted from go/types/infer.go. Try to keep in sync.

	// 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.isParameterizedLocked(t.Elem())

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

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

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

	case *types.Tuple:
		n := t.Len()
		for i := 0; i < n; i++ {
			if w.isParameterizedLocked(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.isParameterizedLocked(t.Params()) || w.isParameterizedLocked(t.Results())

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

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

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

	case *types.Named:
		args := t.TypeArgs()
		// TODO(taking): this does not match go/types/infer.go. Check with rfindley.
		if params := t.TypeParams(); params.Len() > args.Len() {
			return true
		}
		for i, n := 0, args.Len(); i < n; i++ {
			if w.isParameterizedLocked(args.At(i)) {
				return true
			}
		}
		return w.isParameterizedLocked(t.Underlying()) // recurse for types local to parameterized functions

	case *types.TypeParam:
		return true

	default:
		panic(t) // unreachable
	}

	return false
}

// anyParameterized reports whether any element of ts is parameterized.
// Thread-safe.
func (w *tpWalker) anyParameterized(ts []types.Type) bool {
	w.mu.Lock()
	defer w.mu.Unlock()
	for _, t := range ts {
		if w.isParameterizedLocked(t) {
			return true
		}
	}
	return false
}
