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

//go:build go1.18
// +build go1.18

package gcimporter_test

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/importer"
	"go/parser"
	"go/token"
	"go/types"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"

	"golang.org/x/tools/internal/gcimporter"
	"golang.org/x/tools/internal/testenv"
)

// TODO(rfindley): migrate this to testdata, as has been done in the standard library.
func TestGenericExport(t *testing.T) {
	const src = `
package generic

type Any any

type T[A, B any] struct { Left A; Right B }

func (T[P, Q]) m() {}

var X T[int, string] = T[int, string]{1, "hi"}

func ToInt[P interface{ ~int }](p P) int { return int(p) }

var IntID = ToInt[int]

type G[C comparable] int

func ImplicitFunc[T ~int]() {}

type ImplicitType[T ~int] int

// Exercise constant import/export
const C1 = 42
const C2 int = 42
const C3 float64 = 42

type Constraint[T any] interface {
       m(T)
}

// TODO(rfindley): revert to multiple blanks once the restriction on multiple
// blanks is removed from the type checker.
// type Blanks[_ any, _ Constraint[int]] int
// func (Blanks[_, _]) m() {}
type Blanks[_ any] int
func (Blanks[_]) m() {}
`
	testExportSrc(t, []byte(src))
}

func testExportSrc(t *testing.T, src []byte) {
	// This package only handles gc export data.
	if runtime.Compiler != "gc" {
		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
	}
	testenv.NeedsGoBuild(t)

	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, "g.go", src, 0)
	if err != nil {
		t.Fatal(err)
	}
	conf := types.Config{
		Importer: importer.Default(),
	}
	pkg, err := conf.Check("", fset, []*ast.File{f}, nil)
	if err != nil {
		t.Fatal(err)
	}

	// export
	version := gcimporter.IExportVersion
	data, err := iexport(fset, version, pkg)
	if err != nil {
		t.Fatal(err)
	}

	testPkgData(t, fset, version, pkg, data)
}

func TestImportTypeparamTests(t *testing.T) {
	testenv.NeedsGoBuild(t) // to find stdlib export data in the build cache

	// Check go files in test/typeparam.
	rootDir := filepath.Join(runtime.GOROOT(), "test", "typeparam")
	list, err := os.ReadDir(rootDir)
	if err != nil {
		t.Fatal(err)
	}

	if isUnifiedBuilder() {
		t.Skip("unified export data format is currently unsupported")
	}

	for _, entry := range list {
		if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") {
			// For now, only consider standalone go files.
			continue
		}

		t.Run(entry.Name(), func(t *testing.T) {
			filename := filepath.Join(rootDir, entry.Name())
			src, err := os.ReadFile(filename)
			if err != nil {
				t.Fatal(err)
			}

			if !bytes.HasPrefix(src, []byte("// run")) && !bytes.HasPrefix(src, []byte("// compile")) {
				// We're bypassing the logic of run.go here, so be conservative about
				// the files we consider in an attempt to make this test more robust to
				// changes in test/typeparams.
				t.Skipf("not detected as a run test")
			}

			testExportSrc(t, src)
		})
	}
}

func TestRecursiveExport_Issue51219(t *testing.T) {
	const srca = `
package a

type Interaction[DataT InteractionDataConstraint] struct {
}

type InteractionDataConstraint interface {
	[]byte |
		UserCommandInteractionData
}

type UserCommandInteractionData struct {
	resolvedInteractionWithOptions
}

type resolvedInteractionWithOptions struct {
	Resolved Resolved
}

type Resolved struct {
	Users ResolvedData[User]
}

type ResolvedData[T ResolvedDataConstraint] map[uint64]T

type ResolvedDataConstraint interface {
	User | Message
}

type User struct{}

type Message struct {
	Interaction *Interaction[[]byte]
}
`

	const srcb = `
package b

import (
	"a"
)

// InteractionRequest is an incoming request Interaction
type InteractionRequest[T a.InteractionDataConstraint] struct {
	a.Interaction[T]
}
`

	const srcp = `
package p

import (
	"b"
)

// ResponseWriterMock mocks corde's ResponseWriter interface
type ResponseWriterMock struct {
	x b.InteractionRequest[[]byte]
}
`

	importer := &testImporter{
		src: map[string][]byte{
			"a": []byte(srca),
			"b": []byte(srcb),
			"p": []byte(srcp),
		},
		pkgs: make(map[string]*types.Package),
	}
	_, err := importer.Import("p")
	if err != nil {
		t.Fatal(err)
	}
}

// testImporter is a helper to test chains of imports using export data.
type testImporter struct {
	src  map[string][]byte         // original source
	pkgs map[string]*types.Package // memoized imported packages
}

func (t *testImporter) Import(path string) (*types.Package, error) {
	if pkg, ok := t.pkgs[path]; ok {
		return pkg, nil
	}
	src, ok := t.src[path]
	if !ok {
		return nil, fmt.Errorf("unknown path %v", path)
	}

	// Type-check, but don't return this package directly.
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, path+".go", src, 0)
	if err != nil {
		return nil, err
	}
	conf := types.Config{
		Importer: t,
	}
	pkg, err := conf.Check(path, fset, []*ast.File{f}, nil)
	if err != nil {
		return nil, err
	}

	// Export and import to get the package imported from export data.
	exportdata, err := iexport(fset, gcimporter.IExportVersion, pkg)
	if err != nil {
		return nil, err
	}
	imports := make(map[string]*types.Package)
	fset2 := token.NewFileSet()
	_, pkg2, err := gcimporter.IImportData(fset2, imports, exportdata, pkg.Path())
	if err != nil {
		return nil, err
	}
	t.pkgs[path] = pkg2
	return pkg2, nil
}
