// Copyright 2020 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 cache

import (
	"context"
	"os"
	"testing"

	"golang.org/x/tools/internal/lsp/fake"
	"golang.org/x/tools/internal/lsp/source"
	"golang.org/x/tools/internal/span"
)

// osFileSource is a fileSource that just reads from the operating system.
type osFileSource struct{}

func (s osFileSource) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) {
	fi, statErr := os.Stat(uri.Filename())
	if statErr != nil {
		return &fileHandle{
			err: statErr,
			uri: uri,
		}, nil
	}
	fh, err := readFile(ctx, uri, fi.ModTime())
	if err != nil {
		return nil, err
	}
	return fh, nil
}

func TestWorkspaceModule(t *testing.T) {
	tests := []struct {
		desc           string
		initial        string // txtar-encoded
		legacyMode     bool
		initialSource  workspaceSource
		initialModules []string
		initialDirs    []string
		updates        map[string]string
		finalSource    workspaceSource
		finalModules   []string
		finalDirs      []string
	}{
		{
			desc: "legacy mode",
			initial: `
-- go.mod --
module mod.com
-- a/go.mod --
module moda.com`,
			legacyMode:     true,
			initialModules: []string{"./go.mod"},
			initialSource:  legacyWorkspace,
			initialDirs:    []string{"."},
		},
		{
			desc: "nested module",
			initial: `
-- go.mod --
module mod.com
-- a/go.mod --
module moda.com`,
			initialModules: []string{"./go.mod", "a/go.mod"},
			initialSource:  fileSystemWorkspace,
			initialDirs:    []string{".", "a"},
		},
		{
			desc: "removing module",
			initial: `
-- a/go.mod --
module moda.com
-- b/go.mod --
module modb.com`,
			initialModules: []string{"a/go.mod", "b/go.mod"},
			initialSource:  fileSystemWorkspace,
			initialDirs:    []string{".", "a", "b"},
			updates: map[string]string{
				"gopls.mod": `module gopls-workspace

require moda.com v0.0.0-goplsworkspace
replace moda.com => $SANDBOX_WORKDIR/a`,
			},
			finalModules: []string{"a/go.mod"},
			finalSource:  goplsModWorkspace,
			finalDirs:    []string{".", "a"},
		},
		{
			desc: "adding module",
			initial: `
-- gopls.mod --
require moda.com v0.0.0-goplsworkspace
replace moda.com => $SANDBOX_WORKDIR/a
-- a/go.mod --
module moda.com
-- b/go.mod --
module modb.com`,
			initialModules: []string{"a/go.mod"},
			initialSource:  goplsModWorkspace,
			initialDirs:    []string{".", "a"},
			updates: map[string]string{
				"gopls.mod": `module gopls-workspace

require moda.com v0.0.0-goplsworkspace
require modb.com v0.0.0-goplsworkspace

replace moda.com => $SANDBOX_WORKDIR/a
replace modb.com => $SANDBOX_WORKDIR/b`,
			},
			finalModules: []string{"a/go.mod", "b/go.mod"},
			finalSource:  goplsModWorkspace,
			finalDirs:    []string{".", "a", "b"},
		},
		{
			desc: "deleting gopls.mod",
			initial: `
-- gopls.mod --
module gopls-workspace

require moda.com v0.0.0-goplsworkspace
replace moda.com => $SANDBOX_WORKDIR/a
-- a/go.mod --
module moda.com
-- b/go.mod --
module modb.com`,
			initialModules: []string{"a/go.mod"},
			initialSource:  goplsModWorkspace,
			initialDirs:    []string{".", "a"},
			updates: map[string]string{
				"gopls.mod": "",
			},
			finalModules: []string{"a/go.mod", "b/go.mod"},
			finalSource:  fileSystemWorkspace,
			finalDirs:    []string{".", "a", "b"},
		},
		{
			desc: "broken module parsing",
			initial: `
-- a/go.mod --
module moda.com

require gopls.test v0.0.0-goplsworkspace
replace gopls.test => ../../gopls.test // (this path shouldn't matter)
-- b/go.mod --
module modb.com`,
			initialModules: []string{"a/go.mod", "b/go.mod"},
			initialSource:  fileSystemWorkspace,
			initialDirs:    []string{".", "a", "b", "../gopls.test"},
			updates: map[string]string{
				"a/go.mod": `modul moda.com

require gopls.test v0.0.0-goplsworkspace
replace gopls.test => ../../gopls.test2`,
			},
			finalModules: []string{"a/go.mod", "b/go.mod"},
			finalSource:  fileSystemWorkspace,
			// finalDirs should be unchanged: we should preserve dirs in the presence
			// of a broken modfile.
			finalDirs: []string{".", "a", "b", "../gopls.test"},
		},
	}

	for _, test := range tests {
		t.Run(test.desc, func(t *testing.T) {
			ctx := context.Background()
			dir, err := fake.Tempdir(test.initial)
			if err != nil {
				t.Fatal(err)
			}
			defer os.RemoveAll(dir)
			root := span.URIFromPath(dir)

			fs := osFileSource{}
			wm, err := newWorkspace(ctx, root, fs, "", !test.legacyMode)
			if err != nil {
				t.Fatal(err)
			}
			rel := fake.RelativeTo(dir)
			checkWorkspaceModule(t, rel, wm, test.initialSource, test.initialModules)
			gotDirs := wm.dirs(ctx, fs)
			checkWorkspaceDirs(t, rel, gotDirs, test.initialDirs)
			if test.updates != nil {
				changes := make(map[span.URI]*fileChange)
				for k, v := range test.updates {
					if v == "" {
						// for convenience, use this to signal a deletion. TODO: more doc
						err := os.Remove(rel.AbsPath(k))
						if err != nil {
							t.Fatal(err)
						}
					} else {
						fake.WriteFileData(k, []byte(v), rel)
					}
					uri := span.URIFromPath(rel.AbsPath(k))
					fh, err := fs.GetFile(ctx, uri)
					if err != nil {
						t.Fatal(err)
					}
					content, err := fh.Read()
					changes[uri] = &fileChange{
						content:    content,
						exists:     err == nil,
						fileHandle: &closedFile{fh},
					}
				}
				wm, _ := wm.invalidate(ctx, changes)
				checkWorkspaceModule(t, rel, wm, test.finalSource, test.finalModules)
				gotDirs := wm.dirs(ctx, fs)
				checkWorkspaceDirs(t, rel, gotDirs, test.finalDirs)
			}
		})
	}
}

func checkWorkspaceModule(t *testing.T, rel fake.RelativeTo, got *workspace, wantSource workspaceSource, want []string) {
	t.Helper()
	if got.moduleSource != wantSource {
		t.Errorf("module source = %v, want %v", got.moduleSource, wantSource)
	}
	modules := make(map[span.URI]struct{})
	for k := range got.getActiveModFiles() {
		modules[k] = struct{}{}
	}
	for _, modPath := range want {
		path := rel.AbsPath(modPath)
		uri := span.URIFromPath(path)
		if _, ok := modules[uri]; !ok {
			t.Errorf("missing module %q", uri)
		}
		delete(modules, uri)
	}
	for remaining := range modules {
		t.Errorf("unexpected module %q", remaining)
	}
}

func checkWorkspaceDirs(t *testing.T, rel fake.RelativeTo, got []span.URI, want []string) {
	t.Helper()
	gotM := make(map[span.URI]bool)
	for _, dir := range got {
		gotM[dir] = true
	}
	for _, dir := range want {
		path := rel.AbsPath(dir)
		uri := span.URIFromPath(path)
		if !gotM[uri] {
			t.Errorf("missing dir %q", uri)
		}
		delete(gotM, uri)
	}
	for remaining := range gotM {
		t.Errorf("unexpected dir %q", remaining)
	}
}
