// Copyright 2018 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 gopathwalk

import (
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"reflect"
	"runtime"
	"strings"
	"sync"
	"testing"
)

func TestShouldTraverse(t *testing.T) {
	switch runtime.GOOS {
	case "windows", "plan9":
		t.Skipf("skipping symlink-requiring test on %s", runtime.GOOS)
	}

	dir, err := ioutil.TempDir("", "goimports-")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(dir)

	// Note: mapToDir prepends "src" to each element, since
	// mapToDir was made for creating GOPATHs.
	if err := mapToDir(dir, map[string]string{
		"foo/foo2/file.txt":        "",
		"foo/foo2/link-to-src":     "LINK:../../",
		"foo/foo2/link-to-src-foo": "LINK:../../foo",
		"foo/foo2/link-to-dot":     "LINK:.",
		"bar/bar2/file.txt":        "",
		"bar/bar2/link-to-src-foo": "LINK:../../foo",

		"a/b/c": "LINK:../../a/d",
		"a/d/e": "LINK:../../a/b",
	}); err != nil {
		t.Fatal(err)
	}
	tests := []struct {
		dir  string
		file string
		want bool
	}{
		{
			dir:  "src/foo/foo2",
			file: "link-to-src-foo",
			want: false, // loop
		},
		{
			dir:  "src/foo/foo2",
			file: "link-to-src",
			want: false, // loop
		},
		{
			dir:  "src/foo/foo2",
			file: "link-to-dot",
			want: false, // loop
		},
		{
			dir:  "src/bar/bar2",
			file: "link-to-src-foo",
			want: true, // not a loop
		},
		{
			dir:  "src/a/b/c",
			file: "e",
			want: false, // loop: "e" is the same as "b".
		},
	}
	for i, tt := range tests {
		fi, err := os.Stat(filepath.Join(dir, tt.dir, tt.file))
		if err != nil {
			t.Errorf("%d. Stat = %v", i, err)
			continue
		}
		var w walker
		got := w.shouldTraverse(filepath.Join(dir, tt.dir, fi.Name()))
		if got != tt.want {
			t.Errorf("%d. shouldTraverse(%q, %q) = %v; want %v", i, tt.dir, tt.file, got, tt.want)
		}
	}
}

// TestSkip tests that various goimports rules are followed in non-modules mode.
func TestSkip(t *testing.T) {
	dir, err := ioutil.TempDir("", "goimports-")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(dir)

	if err := mapToDir(dir, map[string]string{
		"ignoreme/f.go":     "package ignoreme",     // ignored by .goimportsignore
		"node_modules/f.go": "package nodemodules;", // ignored by hardcoded node_modules filter
		"v/f.go":            "package v;",           // ignored by hardcoded vgo cache rule
		"mod/f.go":          "package mod;",         // ignored by hardcoded vgo cache rule
		"shouldfind/f.go":   "package shouldfind;",  // not ignored

		".goimportsignore": "ignoreme\n",
	}); err != nil {
		t.Fatal(err)
	}

	var found []string
	var mu sync.Mutex
	walkDir(Root{filepath.Join(dir, "src"), RootGOPATH},
		func(root Root, dir string) {
			mu.Lock()
			defer mu.Unlock()
			found = append(found, dir[len(root.Path)+1:])
		}, func(root Root, dir string) bool {
			return false
		}, Options{ModulesEnabled: false, Logf: log.Printf})
	if want := []string{"shouldfind"}; !reflect.DeepEqual(found, want) {
		t.Errorf("expected to find only %v, got %v", want, found)
	}
}

// TestSkipFunction tests that scan successfully skips directories from user callback.
func TestSkipFunction(t *testing.T) {
	dir, err := ioutil.TempDir("", "goimports-")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(dir)

	if err := mapToDir(dir, map[string]string{
		"ignoreme/f.go":           "package ignoreme",    // ignored by skip
		"ignoreme/subignore/f.go": "package subignore",   // also ignored by skip
		"shouldfind/f.go":         "package shouldfind;", // not ignored
	}); err != nil {
		t.Fatal(err)
	}

	var found []string
	var mu sync.Mutex
	walkDir(Root{filepath.Join(dir, "src"), RootGOPATH},
		func(root Root, dir string) {
			mu.Lock()
			defer mu.Unlock()
			found = append(found, dir[len(root.Path)+1:])
		}, func(root Root, dir string) bool {
			return strings.HasSuffix(dir, "ignoreme")
		},
		Options{ModulesEnabled: false})
	if want := []string{"shouldfind"}; !reflect.DeepEqual(found, want) {
		t.Errorf("expected to find only %v, got %v", want, found)
	}
}

func mapToDir(destDir string, files map[string]string) error {
	for path, contents := range files {
		file := filepath.Join(destDir, "src", path)
		if err := os.MkdirAll(filepath.Dir(file), 0755); err != nil {
			return err
		}
		var err error
		if strings.HasPrefix(contents, "LINK:") {
			err = os.Symlink(strings.TrimPrefix(contents, "LINK:"), file)
		} else {
			err = ioutil.WriteFile(file, []byte(contents), 0644)
		}
		if err != nil {
			return err
		}
	}
	return nil
}
