// Copyright 2021 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 main

import (
	"context"
	"net/http"
	"net/http/httptest"
	"os"
	"path"
	"path/filepath"
	"regexp"
	"testing"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/net/html"
	"golang.org/x/pkgsite/internal/proxy/proxytest"
	"golang.org/x/pkgsite/internal/testing/htmlcheck"
	"golang.org/x/pkgsite/internal/testing/testhelper"
)

var (
	in      = htmlcheck.In
	hasText = htmlcheck.HasText
	attr    = htmlcheck.HasAttr

	// href checks for an exact match in an href attribute.
	href = func(val string) htmlcheck.Checker {
		return attr("href", "^"+regexp.QuoteMeta(val)+"$")
	}
)

func TestServer(t *testing.T) {
	repoPath := func(fn string) string { return filepath.Join("..", "..", fn) }

	abs := func(dir string) string {
		a, err := filepath.Abs(dir)
		if err != nil {
			t.Fatal(err)
		}
		return a
	}

	localModule, _ := testhelper.WriteTxtarToTempDir(t, `
-- go.mod --
module example.com/testmod
-- a.go --
package a
`)
	cacheDir := repoPath("internal/fetch/testdata/modcache")
	testModules := proxytest.LoadTestModules(repoPath("internal/proxy/testdata"))
	prox, teardown := proxytest.SetupTestClient(t, testModules)
	defer teardown()

	cfg := func(modifyDefault func(*serverConfig)) serverConfig {
		c := serverConfig{
			paths:         []string{localModule},
			gopathMode:    false,
			useListedMods: true,
			useCache:      true,
			cacheDir:      cacheDir,
			proxy:         prox,
		}
		if modifyDefault != nil {
			modifyDefault(&c)
		}
		return c
	}

	modcacheChecker := in("",
		in(".Documentation", hasText("var V = 1")),
		sourceLinks(path.Join(abs(cacheDir), "modcache.com@v1.0.0"), "a.go"))

	ctx := context.Background()
	for _, test := range []struct {
		name     string
		cfg      serverConfig
		url      string
		wantCode int
		want     htmlcheck.Checker
	}{
		{
			"local",
			cfg(nil),
			"example.com/testmod",
			http.StatusOK,
			in("",
				in(".Documentation", hasText("There is no documentation for this package.")),
				sourceLinks(path.Join(abs(localModule), "example.com/testmod"), "a.go")),
		},
		{
			"modcache",
			cfg(nil),
			"modcache.com@v1.0.0",
			http.StatusOK,
			modcacheChecker,
		},
		{
			"modcache latest",
			cfg(nil),
			"modcache.com",
			http.StatusOK,
			modcacheChecker,
		},
		{
			"modcache unsupported",
			cfg(func(c *serverConfig) {
				c.useCache = false
			}),
			"modcache.com",
			http.StatusFailedDependency, // TODO(rfindley): should this be 404?
			hasText("page is not supported"),
		},
		{
			"proxy",
			cfg(nil),
			"example.com/single/pkg",
			http.StatusOK,
			hasText("G is new in v1.1.0"),
		},
		{
			"proxy unsupported",
			cfg(func(c *serverConfig) {
				c.proxy = nil
			}),
			"example.com/single/pkg",
			http.StatusFailedDependency, // TODO(rfindley): should this be 404?
			hasText("page is not supported"),
		},
		{
			"search",
			cfg(nil),
			"search?q=a",
			http.StatusOK,
			in(".SearchResults",
				hasText("example.com/testmod"),
			),
		},
		{
			"no symbol search",
			cfg(nil),
			"search?q=A", // using a capital letter should not cause symbol search
			http.StatusOK,
			in(".SearchResults",
				hasText("example.com/testmod"),
			),
		},
		{
			"search not found",
			cfg(nil),
			"search?q=zzz",
			http.StatusOK,
			in(".SearchResults",
				hasText("no matches"),
			),
		},
		{
			"search vulns not found",
			cfg(nil),
			"search?q=GO-1234-1234",
			http.StatusOK,
			in(".SearchResults",
				hasText("no matches"),
			),
		},
		{
			"search unsupported",
			cfg(func(c *serverConfig) {
				c.paths = nil
			}),
			"search?q=zzz",
			http.StatusFailedDependency,
			hasText("page is not supported"),
		},
		{
			"vulns unsupported",
			cfg(nil),
			"vuln/",
			http.StatusFailedDependency,
			hasText("page is not supported"),
		},
		// TODO(rfindley): add a test for the standard library once it doesn't go
		// through the stdlib package.
		// See also golang/go#58923.
	} {
		t.Run(test.name, func(t *testing.T) {
			server, err := buildServer(ctx, test.cfg)
			if err != nil {
				t.Fatal(err)
			}
			mux := http.NewServeMux()
			server.Install(mux.Handle, nil, nil)

			w := httptest.NewRecorder()
			mux.ServeHTTP(w, httptest.NewRequest("GET", "/"+test.url, nil))
			if w.Code != test.wantCode {
				t.Fatalf("got status code = %d, want %d", w.Code, test.wantCode)
			}
			doc, err := html.Parse(w.Body)
			if err != nil {
				t.Fatal(err)
			}
			if err := test.want(doc); err != nil {
				if testing.Verbose() {
					html.Render(os.Stdout, doc)
				}
				t.Error(err)
			}
		})
	}
}

func sourceLinks(dir, filename string) htmlcheck.Checker {
	filesPath := path.Join("/files", dir) + "/"
	return in("",
		in(".UnitMeta-repo a", href(filesPath)),
		in(".UnitFiles-titleLink a", href(filesPath)),
		in(".UnitFiles-fileList a", href(filesPath+filename)))
}

func TestCollectPaths(t *testing.T) {
	got := collectPaths([]string{"a", "b,c2,d3", "e4", "f,g"})
	want := []string{"a", "b", "c2", "d3", "e4", "f", "g"}
	if !cmp.Equal(got, want) {
		t.Errorf("got %v, want %v", got, want)
	}
}
