// Copyright 2026 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 client

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"slices"
	"strings"
	"testing"
)

func TestGetPackage(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/v1beta/package/encoding/json" {
			t.Errorf("path = %q, want /v1beta/package/encoding/json", r.URL.Path)
		}
		if got := r.Header.Get("User-Agent"); got != "pkgsite-cli/v1" {
			t.Errorf("User-Agent = %q, want pkgsite-cli/v1", got)
		}
		if got := r.URL.Query().Get("version"); got != "go1.26.0" {
			t.Errorf("version = %q, want go1.26.0", got)
		}
		json.NewEncoder(w).Encode(Package{
			PackageInfo: PackageInfo{
				Path:     "encoding/json",
				Synopsis: "Package json implements encoding and decoding of JSON.",
			},
			ModulePath:        "std",
			Version:           "go1.26.0",
			IsStandardLibrary: true,
		})
	}))
	defer srv.Close()

	c, err := New(srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := c.GetPackage(context.Background(), "encoding/json", "go1.26.0", PackageOptions{})
	if err != nil {
		t.Fatal(err)
	}
	if resp.Path != "encoding/json" {
		t.Errorf("Path = %q, want encoding/json", resp.Path)
	}
	if !resp.IsStandardLibrary {
		t.Error("IsStandardLibrary = false, want true")
	}
}

func TestGetPackageWithFlags(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		q := r.URL.Query()
		if got := q.Get("doc"); got != "md" {
			t.Errorf("doc = %q, want md", got)
		}
		if got := q.Get("imports"); got != "true" {
			t.Errorf("imports = %q, want true", got)
		}
		if got := q.Get("licenses"); got != "true" {
			t.Errorf("licenses = %q, want true", got)
		}
		if got := q.Get("module"); got != "github.com/foo/bar" {
			t.Errorf("module = %q, want github.com/foo/bar", got)
		}
		json.NewEncoder(w).Encode(Package{
			PackageInfo: PackageInfo{
				Path: "github.com/foo/bar/pkg",
			},
			Docs:    "# package pkg",
			Imports: []string{"fmt", "strings"},
		})
	}))
	defer srv.Close()

	c, err := New(srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := c.GetPackage(context.Background(), "github.com/foo/bar/pkg", "", PackageOptions{
		Doc:      "md",
		Imports:  true,
		Licenses: true,
		Module:   "github.com/foo/bar",
	})
	if err != nil {
		t.Fatal(err)
	}
	if resp.Docs != "# package pkg" {
		t.Errorf("Docs = %q, want # package pkg", resp.Docs)
	}
	if len(resp.Imports) != 2 {
		t.Errorf("len(Imports) = %d, want 2", len(resp.Imports))
	}
}

func TestGetModule(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/v1beta/module/golang.org/x/text" {
			t.Errorf("path = %q, want /v1beta/module/golang.org/x/text", r.URL.Path)
		}
		json.NewEncoder(w).Encode(Module{
			Path:    "golang.org/x/text",
			Version: "v0.14.0",
			RepoURL: "https://github.com/golang/text",
		})
	}))
	defer srv.Close()

	c, err := New(srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := c.GetModule(context.Background(), "golang.org/x/text", "v0.14.0", ModuleOptions{})
	if err != nil {
		t.Fatal(err)
	}
	if resp.Version != "v0.14.0" {
		t.Errorf("Version = %q, want v0.14.0", resp.Version)
	}
}

func TestGetVersions(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/v1beta/versions/golang.org/x/text" {
			t.Errorf("path = %q, want /v1beta/versions/golang.org/x/text", r.URL.Path)
		}
		json.NewEncoder(w).Encode(PaginatedResponse[VersionResponse]{
			Items: []VersionResponse{{Version: "v0.14.0"}, {Version: "v0.13.0"}},
			Total: 2,
		})
	}))
	defer srv.Close()

	c, err := New(srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := c.GetVersions(context.Background(), "golang.org/x/text", PaginationOptions{})
	if err != nil {
		t.Fatal(err)
	}
	if len(resp.Items) != 2 {
		t.Errorf("len(Items) = %d, want 2", len(resp.Items))
	}
}

func TestGetVulns(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		json.NewEncoder(w).Encode(PaginatedResponse[Vulnerability]{
			Items: []Vulnerability{{ID: "GO-2023-0001", Details: "A vulnerability."}},
			Total: 1,
		})
	}))
	defer srv.Close()

	c, err := New(srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := c.GetVulns(context.Background(), "golang.org/x/text", "v0.3.0", PaginationOptions{})
	if err != nil {
		t.Fatal(err)
	}
	if len(resp.Items) != 1 {
		t.Errorf("len(Items) = %d, want 1", len(resp.Items))
	}
	if resp.Items[0].ID != "GO-2023-0001" {
		t.Errorf("ID = %q, want GO-2023-0001", resp.Items[0].ID)
	}
}

func TestSearch(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if got := r.URL.Query().Get("q"); got != "json parser" {
			t.Errorf("q = %q, want %q", got, "json parser")
		}
		json.NewEncoder(w).Encode(PaginatedResponse[SearchResult]{
			Items: []SearchResult{{
				PackagePath: "encoding/json",
				ModulePath:  "std",
				Version:     "go1.26.0",
				Synopsis:    "Package json implements encoding and decoding of JSON.",
			}},
			Total: 1,
		})
	}))
	defer srv.Close()

	c, err := New(srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := c.Search(context.Background(), "json parser", SearchOptions{})
	if err != nil {
		t.Fatal(err)
	}
	if len(resp.Items) != 1 {
		t.Errorf("len(Items) = %d, want 1", len(resp.Items))
	}
}

func TestGetSymbols(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		json.NewEncoder(w).Encode(PackageSymbols{
			ModulePath: "std",
			Version:    "go1.26.0",
			Symbols: PaginatedResponse[Symbol]{
				Items: []Symbol{{
					Name:     "Marshal",
					Kind:     "func",
					Synopsis: "func Marshal(v any) ([]byte, error)",
				}},
				Total: 1,
			},
		})
	}))
	defer srv.Close()

	c, err := New(srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := c.GetSymbols(context.Background(), "encoding/json", "", SymbolsOptions{})
	if err != nil {
		t.Fatal(err)
	}
	if resp.Items[0].Name != "Marshal" {
		t.Errorf("Name = %q, want Marshal", resp.Items[0].Name)
	}
}

func TestGetImportedBy(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		json.NewEncoder(w).Encode(PackageImportedBy{
			ModulePath: "std",
			Version:    "go1.26.0",
			ImportedBy: PaginatedResponse[string]{
				Items: []string{"github.com/foo/bar", "github.com/baz/qux"},
				Total: 2,
			},
		})
	}))
	defer srv.Close()

	c, err := New(srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := c.GetImportedBy(context.Background(), "encoding/json", "", ImportedByOptions{})
	if err != nil {
		t.Fatal(err)
	}
	if len(resp.ImportedBy.Items) != 2 {
		t.Errorf("len(ImportedBy.Items) = %d, want 2", len(resp.ImportedBy.Items))
	}
}

func TestAmbiguousPackagePath(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(Error{
			Code:    400,
			Message: "ambiguous package path",
			Candidates: []Candidate{
				{ModulePath: "github.com/foo/bar", PackagePath: "github.com/foo/bar/pkg"},
				{ModulePath: "github.com/foo/bar/pkg", PackagePath: "github.com/foo/bar/pkg"},
			},
		})
	}))
	defer srv.Close()

	c, err := New(srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	_, err = c.GetPackage(context.Background(), "github.com/foo/bar/pkg", "", PackageOptions{})
	if err == nil {
		t.Fatal("expected error")
	}
	msg := err.Error()
	if !strings.Contains(msg, "-module=github.com/foo/bar") {
		t.Errorf("error missing candidate, got:\n%s", msg)
	}
	if !strings.Contains(msg, "-module=github.com/foo/bar/pkg") {
		t.Errorf("error missing candidate, got:\n%s", msg)
	}
}

func TestAPIError(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNotFound)
		json.NewEncoder(w).Encode(Error{Code: 404, Message: "not found"})
	}))
	defer srv.Close()

	c, err := New(srv.URL)
	if err != nil {
		t.Fatal(err)
	}
	_, err = c.GetPackage(context.Background(), "nonexistent/pkg", "", PackageOptions{})
	if err == nil {
		t.Fatal("expected error")
	}
	aerr, ok := err.(*Error)
	if !ok {
		t.Fatalf("error type = %T, want *Error", err)
	}
	if aerr.Code != 404 {
		t.Errorf("Code = %d, want 404", aerr.Code)
	}
}

func TestAllItemsSinglePage(t *testing.T) {
	fetch := func(token string, limit int) (*PaginatedResponse[string], error) {
		return &PaginatedResponse[string]{
			Items:         []string{"item1"},
			Total:         1,
			NextPageToken: "",
		}, nil
	}

	items, total, _, err := AllItems("", 0, fetch)
	if err != nil {
		t.Fatal(err)
	}
	if len(items) != 1 {
		t.Errorf("len(items) = %d, want 1", len(items))
	}
	if total != 1 {
		t.Errorf("total = %d, want 1", total)
	}
}

func TestAllItemsLimit(t *testing.T) {
	const totalItems = 5
	pages := map[string]*PaginatedResponse[string]{
		"": {
			Items:         []string{"a", "b"},
			Total:         totalItems,
			NextPageToken: "p1",
		},
		"p1": {
			Items:         []string{"c", "d"},
			Total:         totalItems,
			NextPageToken: "p2",
		},
		"p2": {
			Items:         []string{"e"},
			Total:         totalItems,
			NextPageToken: "",
		},
	}

	fetch := func(token string, limit int) (*PaginatedResponse[string], error) {
		return pages[token], nil
	}

	tests := []struct {
		name      string
		limit     int
		wantItems []string
		wantTotal int
	}{
		{
			name:      "limit 3",
			limit:     3,
			wantItems: []string{"a", "b", "c"},
			wantTotal: totalItems,
		},
		{
			name:      "no limit",
			wantItems: []string{"a", "b", "c", "d", "e"},
			wantTotal: totalItems,
		},
		{
			name:      "limit larger than total",
			limit:     10,
			wantItems: []string{"a", "b", "c", "d", "e"},
			wantTotal: totalItems,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			items, total, _, err := AllItems("", tt.limit, fetch)
			if err != nil {
				t.Fatal(err)
			}
			if total != tt.wantTotal {
				t.Errorf("total = %d, want %d", total, tt.wantTotal)
			}
			if !slices.Equal(items, tt.wantItems) {
				t.Errorf("items = %v, want %v", items, tt.wantItems)
			}
		})
	}
}

func TestAllItems429(t *testing.T) {
	const totalItems = 5
	pages := map[string]*PaginatedResponse[string]{
		"": {
			Items:         []string{"a", "b"},
			Total:         totalItems,
			NextPageToken: "p1",
		},
		"p1": {
			Items:         []string{"c", "d"},
			Total:         totalItems,
			NextPageToken: "p2",
		},
	}

	fetch := func(token string, limit int) (*PaginatedResponse[string], error) {
		if token == "p2" {
			return nil, &Error{Code: http.StatusTooManyRequests, Message: "Too Many Requests"}
		}
		return pages[token], nil
	}

	items, total, nextToken, err := AllItems("", 0, fetch)
	if err == nil {
		t.Fatal("expected error, got nil")
	}
	if !Is429(err) {
		t.Errorf("expected 429 error, got %v", err)
	}
	wantItems := []string{"a", "b", "c", "d"}
	if !slices.Equal(items, wantItems) {
		t.Errorf("items = %v, want %v", items, wantItems)
	}
	if total != totalItems {
		t.Errorf("total = %d, want %d", total, totalItems)
	}
	if nextToken != "p2" {
		t.Errorf("nextToken = %q, want %q", nextToken, "p2")
	}
}

func TestAllItemsPagination(t *testing.T) {
	const totalItems = 5
	pages := map[string]*PaginatedResponse[string]{
		"": {
			Items:         []string{"a", "b"},
			Total:         totalItems,
			NextPageToken: "p1",
		},
		"p1": {
			Items:         []string{"c", "d"},
			Total:         totalItems,
			NextPageToken: "p2",
		},
		"p2": {
			Items:         []string{"e"},
			Total:         totalItems,
			NextPageToken: "",
		},
	}
	fetch := func(token string, limit int) (*PaginatedResponse[string], error) {
		return pages[token], nil
	}

	t.Run("basic 3 pages successive", func(t *testing.T) {
		steps := []struct {
			limit     int
			wantItems []string
			wantToken string
		}{
			{limit: 2, wantItems: []string{"a", "b"}, wantToken: "p1"},
			{limit: 2, wantItems: []string{"c", "d"}, wantToken: "p2"},
			{limit: 2, wantItems: []string{"e"}, wantToken: ""},
		}

		token := ""
		for i, step := range steps {
			items, total, nextToken, err := AllItems(token, step.limit, fetch)
			if err != nil {
				t.Fatalf("step %d: %v", i, err)
			}
			if !slices.Equal(items, step.wantItems) {
				t.Errorf("step %d: items = %v, want %v", i, items, step.wantItems)
			}
			if total != totalItems {
				t.Errorf("step %d: total = %d, want %d", i, total, totalItems)
			}
			if nextToken != step.wantToken {
				t.Errorf("step %d: nextToken = %q, want %q", i, nextToken, step.wantToken)
			}
			token = nextToken
		}
	})

	for _, test := range []struct {
		name      string
		limit     int
		want      []string
		nextToken string
	}{
		{
			"limit within first page",
			1,
			[]string{"a"},
			"",
		},
		{
			"limit within second page",
			3,
			[]string{"a", "b", "c"},
			"p1",
		},
	} {
		t.Run(test.name, func(t *testing.T) {
			items, total, nextToken, err := AllItems("", test.limit, fetch)
			if err != nil {
				t.Fatal(err)
			}
			if !slices.Equal(items, test.want) {
				t.Errorf("items = %v, want %v", items, test.want)
			}
			if total != totalItems {
				t.Errorf("total = %d, want %d", total, totalItems)
			}
			if nextToken != test.nextToken {
				t.Errorf("nextToken = %q, want %q", nextToken, test.nextToken)
			}
		})
	}
}
