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

import (
	"sort"
	"strings"
	"testing"

	. "golang.org/x/tools/gopls/internal/lsp/regtest"
	"golang.org/x/tools/internal/testenv"
)

// This file contains regression tests for the directoryFilters setting.
//
// TODO:
//  - consolidate some of these tests into a single test
//  - add more tests for changing directory filters

func TestDirectoryFilters(t *testing.T) {
	WithOptions(
		ProxyFiles(workspaceProxy),
		WorkspaceFolders("pkg"),
		Settings{
			"directoryFilters": []string{"-inner"},
		},
	).Run(t, workspaceModule, func(t *testing.T, env *Env) {
		syms := env.Symbol("Hi")
		sort.Slice(syms, func(i, j int) bool { return syms[i].ContainerName < syms[j].ContainerName })
		for _, s := range syms {
			if strings.Contains(s.ContainerName, "inner") {
				t.Errorf("WorkspaceSymbol: found symbol %q with container %q, want \"inner\" excluded", s.Name, s.ContainerName)
			}
		}
	})
}

func TestDirectoryFiltersLoads(t *testing.T) {
	// exclude, and its error, should be excluded from the workspace.
	const files = `
-- go.mod --
module example.com

go 1.12
-- exclude/exclude.go --
package exclude

const _ = Nonexistant
`

	WithOptions(
		Settings{"directoryFilters": []string{"-exclude"}},
	).Run(t, files, func(t *testing.T, env *Env) {
		env.OnceMet(
			InitialWorkspaceLoad,
			NoDiagnostics(ForFile("exclude/x.go")),
		)
	})
}

func TestDirectoryFiltersTransitiveDep(t *testing.T) {
	// Even though exclude is excluded from the workspace, it should
	// still be importable as a non-workspace package.
	const files = `
-- go.mod --
module example.com

go 1.12
-- include/include.go --
package include
import "example.com/exclude"

const _ = exclude.X
-- exclude/exclude.go --
package exclude

const _ = Nonexistant // should be ignored, since this is a non-workspace package
const X = 1
`

	WithOptions(
		Settings{"directoryFilters": []string{"-exclude"}},
	).Run(t, files, func(t *testing.T, env *Env) {
		env.OnceMet(
			InitialWorkspaceLoad,
			NoDiagnostics(ForFile("exclude/exclude.go")), // filtered out
			NoDiagnostics(ForFile("include/include.go")), // successfully builds
		)
	})
}

func TestDirectoryFiltersWorkspaceModules(t *testing.T) {
	// Define a module include.com which should be in the workspace, plus a
	// module exclude.com which should be excluded and therefore come from
	// the proxy.
	const files = `
-- include/go.mod --
module include.com

go 1.12

require exclude.com v1.0.0

-- include/go.sum --
exclude.com v1.0.0 h1:Q5QSfDXY5qyNCBeUiWovUGqcLCRZKoTs9XdBeVz+w1I=
exclude.com v1.0.0/go.mod h1:hFox2uDlNB2s2Jfd9tHlQVfgqUiLVTmh6ZKat4cvnj4=

-- include/include.go --
package include

import "exclude.com"

var _ = exclude.X // satisfied only by the workspace version
-- exclude/go.mod --
module exclude.com

go 1.12
-- exclude/exclude.go --
package exclude

const X = 1
`
	const proxy = `
-- exclude.com@v1.0.0/go.mod --
module exclude.com

go 1.12
-- exclude.com@v1.0.0/exclude.go --
package exclude
`
	WithOptions(
		Modes(Experimental),
		ProxyFiles(proxy),
		Settings{"directoryFilters": []string{"-exclude"}},
	).Run(t, files, func(t *testing.T, env *Env) {
		env.Await(Diagnostics(env.AtRegexp("include/include.go", `exclude.(X)`)))
	})
}

// Test for golang/go#46438: support for '**' in directory filters.
func TestDirectoryFilters_Wildcard(t *testing.T) {
	filters := []string{"-**/bye"}
	WithOptions(
		ProxyFiles(workspaceProxy),
		WorkspaceFolders("pkg"),
		Settings{
			"directoryFilters": filters,
		},
	).Run(t, workspaceModule, func(t *testing.T, env *Env) {
		syms := env.Symbol("Bye")
		sort.Slice(syms, func(i, j int) bool { return syms[i].ContainerName < syms[j].ContainerName })
		for _, s := range syms {
			if strings.Contains(s.ContainerName, "bye") {
				t.Errorf("WorkspaceSymbol: found symbol %q with container %q with filters %v", s.Name, s.ContainerName, filters)
			}
		}
	})
}

// Test for golang/go#52993: wildcard directoryFilters should apply to
// goimports scanning as well.
func TestDirectoryFilters_ImportScanning(t *testing.T) {
	const files = `
-- go.mod --
module mod.test

go 1.12
-- main.go --
package main

func main() {
	bye.Goodbye()
}
-- p/bye/bye.go --
package bye

func Goodbye() {}
`

	WithOptions(
		Settings{
			"directoryFilters": []string{"-**/bye"},
		},
		// This test breaks in 'Experimental' mode, because with
		// experimentalWorkspaceModule set we the goimports scan behaves
		// differently.
		//
		// Since this feature is going away (golang/go#52897), don't investigate.
		Modes(Default),
	).Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("main.go")
		beforeSave := env.BufferText("main.go")
		env.OrganizeImports("main.go")
		got := env.BufferText("main.go")
		if got != beforeSave {
			t.Errorf("after organizeImports code action, got modified buffer:\n%s", got)
		}
	})
}

// Test for golang/go#52993: non-wildcard directoryFilters should still be
// applied relative to the workspace folder, not the module root.
func TestDirectoryFilters_MultiRootImportScanning(t *testing.T) {
	testenv.NeedsGo1Point(t, 18) // uses go.work

	const files = `
-- go.work --
go 1.18

use (
	a
	b
)
-- a/go.mod --
module mod1.test

go 1.18
-- a/main.go --
package main

func main() {
	hi.Hi()
}
-- a/hi/hi.go --
package hi

func Hi() {}
-- b/go.mod --
module mod2.test

go 1.18
-- b/main.go --
package main

func main() {
	hi.Hi()
}
-- b/hi/hi.go --
package hi

func Hi() {}
`

	WithOptions(
		Settings{
			"directoryFilters": []string{"-hi"}, // this test fails with -**/hi
		},
	).Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("a/main.go")
		beforeSave := env.BufferText("a/main.go")
		env.OrganizeImports("a/main.go")
		got := env.BufferText("a/main.go")
		if got == beforeSave {
			t.Errorf("after organizeImports code action, got identical buffer:\n%s", got)
		}
	})
}
