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

import (
	"context"
	"errors"
	"net/http"
	"strings"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"golang.org/x/pkgsite/internal"
	"golang.org/x/pkgsite/internal/derrors"
	"golang.org/x/pkgsite/internal/experiment"
	"golang.org/x/pkgsite/internal/postgres"
	"golang.org/x/pkgsite/internal/testing/sample"
)

func TestPreviousFetchStatusAndResponse(t *testing.T) {
	ctx := context.Background()

	for _, mod := range []struct {
		path      string
		goModPath string
		status    int
	}{
		{"mvdan.cc/sh", "", 200},
		{"mvdan.cc", "", 404},
		{"400.mod/foo/bar", "", 400},
		{"400.mod/foo", "", 404},
		{"400.mod", "", 404},
		{"github.com/alternative/ok", "github.com/vanity", 491},
		{"github.com/alternative/ok/path", "", 404},
		{"github.com/alternative/bad", "vanity", 491},
		{"bad.mod/foo/bar", "", 490},
		{"bad.mod/foo", "", 404},
		{"bad.mod", "", 490},
		{"500.mod/foo", "", 404},
		{"500.mod", "", 500},
		{"reprocess.mod/foo", "", 520},
	} {
		goModPath := mod.goModPath
		if goModPath == "" {
			goModPath = mod.path
		}
		if err := testDB.UpsertVersionMap(ctx, &internal.VersionMap{
			ModulePath:       mod.path,
			RequestedVersion: internal.LatestVersion,
			ResolvedVersion:  sample.VersionString,
			Status:           mod.status,
			GoModPath:        goModPath,
		}); err != nil {
			t.Fatal(err)
		}
	}

	for _, test := range []struct {
		name, path string
		status     int
	}{
		{"bad request at path root", "400.mod/foo/bar", 404},
		{"bad request at mod but 404 at path", "400.mod/foo", 404},
		{"alternative mod", "github.com/alternative/ok", 491},
		{"alternative mod package path", "github.com/alternative/ok/path", 491},
		{"alternative mod bad module path", "github.com/alternative/bad", 404},
		{"bad module at path", "bad.mod/foo/bar", 404},
		{"bad module at mod but 404 at path", "bad.mod/foo", 404},
		{"500", "500.mod/foo", 500},
		{"mod to reprocess", "reprocess.mod/foo", 404},
	} {
		t.Run(test.name, func(t *testing.T) {
			fr, err := previousFetchStatusAndResponse(ctx, testDB, test.path, internal.LatestVersion)
			if err != nil {
				t.Fatal(err)
			}
			if fr.status != test.status {
				t.Errorf("got %v; want %v", fr.status, test.status)
			}
		})
	}

	for _, test := range []struct {
		name, path string
	}{
		{"path never fetched", "github.com/nonexistent"},
		{"path never fetched, but top level mod fetched", "mvdan.cc/sh/v3"},
	} {
		t.Run(test.name, func(t *testing.T) {
			_, err := previousFetchStatusAndResponse(ctx, testDB, test.path, internal.LatestVersion)
			if !errors.Is(err, derrors.NotFound) {
				t.Errorf("got %v; want %v", err, derrors.NotFound)
			}
		})
	}
}

func TestPreviousFetchStatusAndResponse_PathExistsAtNonV1(t *testing.T) {
	ctx := context.Background()

	if err := testDB.InsertModule(ctx, sample.Module(sample.ModulePath+"/v4", "v4.0.0", "foo")); err != nil {
		t.Fatal(err)
	}

	for _, mod := range []struct {
		path, version string
		status        int
	}{
		{sample.ModulePath, "v1.0.0", http.StatusNotFound},
		{sample.ModulePath + "/foo", "v4.0.0", http.StatusNotFound},
		{sample.ModulePath + "/v4", "v4.0.0", http.StatusOK},
	} {
		if err := testDB.UpsertVersionMap(ctx, &internal.VersionMap{
			ModulePath:       mod.path,
			RequestedVersion: internal.LatestVersion,
			ResolvedVersion:  mod.version,
			Status:           mod.status,
			GoModPath:        mod.path,
		}); err != nil {
			t.Fatal(err)
		}
	}

	checkPath := func(ctx context.Context, t *testing.T, testDB *postgres.DB, path, wantPath string, status int) {
		got, err := previousFetchStatusAndResponse(ctx, testDB, path, internal.LatestVersion)
		if err != nil {
			t.Fatal(err)
		}
		want := &fetchResult{
			modulePath: wantPath,
			goModPath:  wantPath,
			status:     status,
		}
		if diff := cmp.Diff(want, got,
			cmp.AllowUnexported(fetchResult{}),
			cmpopts.IgnoreFields(fetchResult{}, "responseText")); diff != "" {
			t.Errorf("mismatch (-want, +got):\n%s", diff)
		}
	}

	for _, test := range []struct {
		name, path, want string
	}{
		{"module path not at v1", sample.ModulePath, sample.ModulePath + "/v4"},
		{"import path not at v1", sample.ModulePath + "/foo", sample.ModulePath + "/v4/foo"},
	} {
		t.Run(test.name, func(t *testing.T) {
			want := strings.ReplaceAll(test.want, "/v4", "")
			checkPath(ctx, t, testDB, test.path, want, http.StatusNotFound)
		})
		t.Run(test.name+"not-at-v1", func(t *testing.T) {
			ctx := experiment.NewContext(ctx, internal.ExperimentNotAtV1)
			checkPath(ctx, t, testDB, test.path, test.want, http.StatusFound)
		})
	}
}
