// Copyright 2023 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 (
	"testing"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/tools/gopls/internal/cache"
	"golang.org/x/tools/gopls/internal/protocol/command"

	. "golang.org/x/tools/gopls/internal/test/integration"
)

func TestAddAndRemoveGoWork(t *testing.T) {
	// Use a workspace with a module in the root directory to exercise the case
	// where a go.work is added to the existing root directory. This verifies
	// that we're detecting changes to the module source, not just the root
	// directory.
	const nomod = `
-- go.mod --
module a.com

go 1.16
-- main.go --
package main

func main() {}
-- b/go.mod --
module b.com

go 1.16
-- b/main.go --
package main

func main() {}
`
	WithOptions(
		Modes(Default),
	).Run(t, nomod, func(t *testing.T, env *Env) {
		env.OpenFile("main.go")
		env.OpenFile("b/main.go")

		summary := func(typ cache.ViewType, root, folder string) command.View {
			return command.View{
				Type:   typ.String(),
				Root:   env.Sandbox.Workdir.URI(root),
				Folder: env.Sandbox.Workdir.URI(folder),
			}
		}
		checkViews := func(want ...command.View) {
			got := env.Views()
			if diff := cmp.Diff(want, got); diff != "" {
				t.Errorf("SummarizeViews() mismatch (-want +got):\n%s", diff)
			}
		}

		// Zero-config gopls makes this work.
		env.AfterChange(
			NoDiagnostics(ForFile("main.go")),
			NoDiagnostics(env.AtRegexp("b/main.go", "package (main)")),
		)
		checkViews(summary(cache.GoModView, ".", "."), summary(cache.GoModView, "b", "."))

		env.WriteWorkspaceFile("go.work", `go 1.16

use (
	.
	b
)
`)
		env.AfterChange(NoDiagnostics())
		checkViews(summary(cache.GoWorkView, ".", "."))

		// Removing the go.work file should put us back where we started.
		env.RemoveWorkspaceFile("go.work")

		// Again, zero-config gopls makes this work.
		env.AfterChange(
			NoDiagnostics(ForFile("main.go")),
			NoDiagnostics(env.AtRegexp("b/main.go", "package (main)")),
		)
		checkViews(summary(cache.GoModView, ".", "."), summary(cache.GoModView, "b", "."))

		// Close and reopen b, to ensure the views are adjusted accordingly.
		env.CloseBuffer("b/main.go")
		env.AfterChange()
		checkViews(summary(cache.GoModView, ".", "."))

		env.OpenFile("b/main.go")
		env.AfterChange()
		checkViews(summary(cache.GoModView, ".", "."), summary(cache.GoModView, "b", "."))
	})
}

func TestOpenAndClosePorts(t *testing.T) {
	// This test checks that as we open and close files requiring a different
	// port, the set of Views is adjusted accordingly.
	const files = `
-- go.mod --
module a.com/a

go 1.20

-- a_linux.go --
package a

-- a_darwin.go --
package a

-- a_windows.go --
package a
`

	WithOptions(
		EnvVars{
			"GOOS": "linux", // assume that linux is the default GOOS
		},
	).Run(t, files, func(t *testing.T, env *Env) {
		summary := func(envOverlay ...string) command.View {
			return command.View{
				Type:       cache.GoModView.String(),
				Root:       env.Sandbox.Workdir.URI("."),
				Folder:     env.Sandbox.Workdir.URI("."),
				EnvOverlay: envOverlay,
			}
		}
		checkViews := func(want ...command.View) {
			got := env.Views()
			if diff := cmp.Diff(want, got); diff != "" {
				t.Errorf("SummarizeViews() mismatch (-want +got):\n%s", diff)
			}
		}
		checkViews(summary())
		env.OpenFile("a_linux.go")
		checkViews(summary())
		env.OpenFile("a_darwin.go")
		checkViews(
			summary(),
			summary("GOARCH=amd64", "GOOS=darwin"),
		)
		env.OpenFile("a_windows.go")
		checkViews(
			summary(),
			summary("GOARCH=amd64", "GOOS=darwin"),
			summary("GOARCH=amd64", "GOOS=windows"),
		)
		env.CloseBuffer("a_darwin.go")
		checkViews(
			summary(),
			summary("GOARCH=amd64", "GOOS=windows"),
		)
		env.CloseBuffer("a_linux.go")
		checkViews(
			summary(),
			summary("GOARCH=amd64", "GOOS=windows"),
		)
		env.CloseBuffer("a_windows.go")
		checkViews(summary())
	})
}

func TestCriticalErrorsInOrphanedFiles(t *testing.T) {
	// This test checks that as we open and close files requiring a different
	// port, the set of Views is adjusted accordingly.
	const files = `
-- go.mod --
modul golang.org/lsptests/broken

go 1.20

-- a.go --
package broken

const C = 0
`

	Run(t, files, func(t *testing.T, env *Env) {
		env.OpenFile("a.go")
		env.AfterChange(
			Diagnostics(env.AtRegexp("go.mod", "modul")),
			Diagnostics(env.AtRegexp("a.go", "broken"), WithMessage("initialization failed")),
		)
	})
}
