// 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 != "/v1/package/encoding/json" {
			t.Errorf("path = %q, want /v1/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 != "/v1/module/golang.org/x/text" {
			t.Errorf("path = %q, want /v1/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 != "/v1/versions/golang.org/x/text" {
			t.Errorf("path = %q, want /v1/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)
			}
		})
	}
}
