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

import (
	"context"
	"errors"
	"os"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/google/safehtml/template"
	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/fetch"
	"golang.org/x/pkgsite/internal/godoc/dochtml"
	"golang.org/x/pkgsite/internal/licenses"
	"golang.org/x/pkgsite/internal/stdlib"
	"golang.org/x/pkgsite/internal/testing/testhelper"
)

var (
	ctx        context.Context
	cancel     func()
	datasource *DataSource
)

func setup(t *testing.T) (context.Context, func(), *DataSource, error) {
	t.Helper()

	// Setup only once.
	if datasource != nil {
		return ctx, cancel, datasource, nil
	}
	licenses.OmitExceptions = true
	modules := []map[string]string{
		{
			"go.mod":        "module github.com/my/module\n\ngo 1.12",
			"LICENSE":       testhelper.BSD0License,
			"README.md":     "README FILE FOR TESTING.",
			"bar/COPYING":   testhelper.MITLicense,
			"bar/README.md": "Another README FILE FOR TESTING.",
			"bar/bar.go": `
			// package bar
			package bar

			// Bar returns the string "bar".
			func Bar() string {
				return "bar"
			}`,
			"foo/LICENSE.md": testhelper.MITLicense,
			"foo/foo.go": `
			// package foo
			package foo

			import (
				"fmt"

				"github.com/my/module/bar"
			)

			// FooBar returns the string "foo bar".
			func FooBar() string {
				return fmt.Sprintf("foo %s", bar.Bar())
			}`,
		},
		{
			"go.mod":  "module github.com/no/license\n\ngo 1.12",
			"LICENSE": "unknown",
			"bar/bar.go": `
			// package bar
			package bar

			// Bar returns the string "bar".
			func Bar() string {
				return "bar"
			}`,
		},
	}

	dochtml.LoadTemplates(template.TrustedSourceFromConstant("../../static/doc"))
	datasource = New()
	ctx, cancel = context.WithTimeout(context.Background(), 20*time.Second)
	for _, module := range modules {
		directory, err := testhelper.CreateTestDirectory(module)
		if err != nil {
			return ctx, func() { cancel() }, nil, err
		}
		defer os.RemoveAll(directory)

		err = datasource.Load(ctx, directory)
		if err != nil {
			return ctx, func() { cancel() }, nil, err
		}
	}

	return ctx, func() { cancel() }, datasource, nil
}

func TestGetUnitMeta(t *testing.T) {
	ctx, cancel, ds, err := setup(t)
	if err != nil {
		t.Fatalf("setup failed: %s", err.Error())
	}
	defer cancel()

	for _, test := range []struct {
		path, modulePath string
		want             *internal.UnitMeta
		wantErr          error
	}{
		{
			path:       "github.com/my/module",
			modulePath: "github.com/my/module",
			want: &internal.UnitMeta{
				Path: "github.com/my/module",
				ModuleInfo: internal.ModuleInfo{
					ModulePath:        "github.com/my/module",
					Version:           fetch.LocalVersion,
					CommitTime:        fetch.LocalCommitTime,
					IsRedistributable: true,
				},
				IsRedistributable: true,
			},
		},
		{
			path:       "github.com/my/module/bar",
			modulePath: "github.com/my/module",
			want: &internal.UnitMeta{
				Path: "github.com/my/module/bar",
				Name: "bar",
				ModuleInfo: internal.ModuleInfo{
					ModulePath:        "github.com/my/module",
					Version:           fetch.LocalVersion,
					CommitTime:        fetch.LocalCommitTime,
					IsRedistributable: true,
				},
				IsRedistributable: true,
			},
		},
		{
			path:       "github.com/my/module/foo",
			modulePath: "github.com/my/module",
			want: &internal.UnitMeta{
				Path: "github.com/my/module/foo",
				Name: "foo",
				ModuleInfo: internal.ModuleInfo{
					ModulePath:        "github.com/my/module",
					IsRedistributable: true,
					Version:           fetch.LocalVersion,
					CommitTime:        fetch.LocalCommitTime,
				},
				IsRedistributable: true,
			},
		},
		{
			path:       "github.com/my/module/bar",
			modulePath: internal.UnknownModulePath,
			want: &internal.UnitMeta{
				Path:              "github.com/my/module/bar",
				Name:              "bar",
				IsRedistributable: true,
				ModuleInfo: internal.ModuleInfo{
					ModulePath:        "github.com/my/module",
					Version:           fetch.LocalVersion,
					CommitTime:        fetch.LocalCommitTime,
					IsRedistributable: true,
				},
			},
		},
		{
			path:       "github.com/not/loaded",
			modulePath: internal.UnknownModulePath,
			wantErr:    derrors.NotFound,
		},
		{
			path:       "net/http",
			modulePath: stdlib.ModulePath,
			wantErr:    derrors.NotFound,
		},
	} {
		t.Run(test.path, func(t *testing.T) {
			got, err := ds.GetUnitMeta(ctx, test.path, test.modulePath, fetch.LocalVersion)
			if test.wantErr != nil {
				if !errors.Is(err, test.wantErr) {
					t.Errorf("GetUnitMeta(%q, %q): %v; wantErr = %v)", test.path, test.modulePath, err, test.wantErr)
				}
			} else {
				if err != nil {
					t.Fatal(err)
				}
				if diff := cmp.Diff(test.want, got); diff != "" {
					t.Errorf("mismatch (-want +got):\n%s", diff)

				}
			}
		})
	}
}

func TestGetUnit(t *testing.T) {
	// This is a simple test to verify that data is fetched correctly. The
	// return value of FetchResult is tested in internal/fetch so no need
	// to repeat it.
	ctx, cancel, ds, err := setup(t)
	if err != nil {
		t.Fatalf("setup failed: %s", err.Error())
	}
	defer cancel()

	for _, test := range []struct {
		path, modulePath string
		wantLoaded       bool
	}{
		{
			path:       "github.com/my/module",
			modulePath: "github.com/my/module",
			wantLoaded: true,
		},
		{
			path:       "github.com/my/module/foo",
			modulePath: "github.com/my/module",
			wantLoaded: true,
		},
		{
			path:       "github.com/no/license/bar",
			modulePath: "github.com/no/license",
			wantLoaded: true,
		},
		{
			path:       "github.com/not/loaded",
			modulePath: internal.UnknownModulePath,
		},
	} {
		t.Run(test.path, func(t *testing.T) {
			um := &internal.UnitMeta{
				Path:       test.path,
				ModuleInfo: internal.ModuleInfo{ModulePath: test.modulePath},
			}
			got, err := ds.GetUnit(ctx, um, 0, internal.BuildContext{})
			if !test.wantLoaded {
				if err == nil {
					t.Fatalf("returned not loaded module %q", test.path)
				}
				return
			}
			if err != nil {
				t.Fatalf("failed for %q: %q", test.path, err.Error())
			}

			if gotEmpty := (got.Documentation == nil && got.Readme == nil); gotEmpty {
				t.Errorf("%q: gotEmpty = %t", test.path, gotEmpty)
			}
		})
	}
}
