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

import (
	"fmt"
	"io"
	"strings"

	"golang.org/x/pkgsite/cmd/internal/pkgsite-cli/client"
)

// Result types combine base entity data with optional supplementary data.
// These are used for both text formatting and JSON output.

type packageResult struct {
	Package    *client.Package                          `json:"package"`
	Symbols    *client.PaginatedResponse[client.Symbol] `json:"symbols,omitempty"`
	ImportedBy *client.PackageImportedBy                `json:"importedBy,omitempty"`
}

type moduleResult struct {
	Module   *client.Module                                          `json:"module"`
	Versions *client.PaginatedResponse[client.VersionResponse]       `json:"versions,omitempty"`
	Vulns    *client.PaginatedResponse[client.Vulnerability]         `json:"vulns,omitempty"`
	Packages *client.PaginatedResponse[client.ModulePackageResponse] `json:"packages,omitempty"`
}

func formatPackage(w io.Writer, r packageResult) {
	p := r.Package
	if p.IsStandardLibrary {
		fmt.Fprintf(w, "%s (standard library)\n", p.Path)
	} else {
		fmt.Fprintf(w, "%s\n", p.Path)
	}
	fmt.Fprintf(w, "  Name:     %s\n", p.Name)
	fmt.Fprintf(w, "  Module:   %s\n", p.ModulePath)
	version := p.Version
	if p.IsLatest {
		version += " (latest)"
	}
	fmt.Fprintf(w, "  Version:  %s\n", version)
	if p.Synopsis != "" {
		fmt.Fprintf(w, "  Synopsis: %s\n", p.Synopsis)
	}
	if p.GOOS != "" && p.GOARCH != "" {
		fmt.Fprintf(w, "  Context:  %s/%s\n", p.GOOS, p.GOARCH)
	}

	if p.Docs != "" {
		fmt.Fprintln(w)
		fmt.Fprintln(w, p.Docs)
	}

	if len(p.Imports) > 0 {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "Imports:")
		for _, imp := range p.Imports {
			fmt.Fprintf(w, "  %s\n", imp)
		}
	}

	if len(p.Licenses) > 0 {
		fmt.Fprintln(w)
		formatLicenses(w, p.Licenses)
	}

	if r.Symbols != nil && len(r.Symbols.Items) > 0 {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "Symbols:")
		for _, s := range r.Symbols.Items {
			if s.Synopsis != "" {
				fmt.Fprintf(w, "  %s\n", s.Synopsis)
			} else {
				fmt.Fprintf(w, "  %s %s\n", s.Kind, s.Name)
			}
		}
		if t := r.Symbols.NextPageToken; t != "" {
			fmt.Fprintf(w, "  next page token: %s\n", t)
		}
		formatPaginationHint(w, len(r.Symbols.Items), r.Symbols.Total, "symbol-token")
	}

	if r.ImportedBy != nil {
		ib := r.ImportedBy.ImportedBy
		if len(ib.Items) > 0 {
			fmt.Fprintln(w)
			fmt.Fprintln(w, "Imported by:")
			for _, pkg := range ib.Items {
				fmt.Fprintf(w, "  %s\n", pkg)
			}
			if t := ib.NextPageToken; t != "" {
				fmt.Fprintf(w, "  next page token: %s\n", t)
			}
			formatPaginationHint(w, len(ib.Items), ib.Total, "imported-by-token")
		}
	}
}

func formatModule(w io.Writer, r moduleResult) {
	m := r.Module
	fmt.Fprintf(w, "%s\n", m.Path)
	version := m.Version
	if m.IsLatest {
		version += " (latest)"
	}
	fmt.Fprintf(w, "  Version:          %s\n", version)
	if m.RepoURL != "" {
		fmt.Fprintf(w, "  Repository:       %s\n", m.RepoURL)
	}
	fmt.Fprintf(w, "  Has go.mod:       %s\n", yesNo(m.HasGoMod))
	fmt.Fprintf(w, "  Redistributable:  %s\n", yesNo(m.IsRedistributable))

	if m.Readme != nil {
		fmt.Fprintln(w)
		fmt.Fprintf(w, "README (%s):\n", m.Readme.Filepath)
		fmt.Fprintln(w, m.Readme.Contents)
	}

	if len(m.Licenses) > 0 {
		fmt.Fprintln(w)
		formatLicenses(w, m.Licenses)
	}

	if r.Versions != nil && len(r.Versions.Items) > 0 {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "Versions:")
		for _, v := range r.Versions.Items {
			fmt.Fprintf(w, "  %s\n", v.Version)
		}
		if t := r.Versions.NextPageToken; t != "" {
			fmt.Fprintf(w, "  next page token: %s\n", t)
		}
		formatPaginationHint(w, len(r.Versions.Items), r.Versions.Total, "versions-token")
	}

	if r.Vulns != nil && len(r.Vulns.Items) > 0 {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "Vulnerabilities:")
		for _, v := range r.Vulns.Items {
			fmt.Fprintf(w, "  %s\n", v.ID)
			if v.Summary != "" {
				fmt.Fprintf(w, "    %s\n", v.Summary)
			} else if v.Details != "" {
				fmt.Fprintf(w, "    %s\n", firstLine(v.Details))
			}
			if v.FixedVersion != "" {
				fmt.Fprintf(w, "    Fixed in: %s\n", v.FixedVersion)
			}
		}
		if t := r.Vulns.NextPageToken; t != "" {
			fmt.Fprintf(w, "  next page token: %s\n", t)
		}
		formatPaginationHint(w, len(r.Vulns.Items), r.Vulns.Total, "vulns-token")
	}

	if r.Packages != nil && len(r.Packages.Items) > 0 {
		fmt.Fprintln(w)
		fmt.Fprintln(w, "Packages:")
		for _, p := range r.Packages.Items {
			if p.Synopsis != "" {
				fmt.Fprintf(w, "  %-40s %s\n", p.Path, p.Synopsis)
			} else {
				fmt.Fprintf(w, "  %s\n", p.Path)
			}
		}
		if t := r.Packages.NextPageToken; t != "" {
			fmt.Fprintf(w, "  next page token: %s\n", t)
		}
		formatPaginationHint(w, len(r.Packages.Items), r.Packages.Total, "packages-token")
	}
}

func formatSearch(w io.Writer, r *client.PaginatedResponse[client.SearchResult]) {
	if len(r.Items) == 0 {
		fmt.Fprintln(w, "No results.")
		return
	}
	for _, sr := range r.Items {
		formatSearchResult(w, sr)
	}
	// Don't display the page token: search doesn't use one.
	formatPaginationHint(w, len(r.Items), r.Total, "")
}

func formatSearchResult(w io.Writer, sr client.SearchResult) {
	fmt.Fprintf(w, "%s\n", sr.PackagePath)
	fmt.Fprintf(w, "  Module:   %s@%s\n", sr.ModulePath, sr.Version)
	if sr.Synopsis != "" {
		fmt.Fprintf(w, "  Synopsis: %s\n", sr.Synopsis)
	}
	fmt.Fprintln(w)
}

func formatLicenses(w io.Writer, licenses []client.License) {
	fmt.Fprintln(w, "Licenses:")
	for _, l := range licenses {
		fmt.Fprintf(w, "  %s (%s)\n", strings.Join(l.Types, ", "), l.FilePath)
	}
}

func formatPaginationHint(w io.Writer, shown, total int, flagName string) {
	if total > shown {
		fmt.Fprintf(w, "  Showing %d of %d.", shown, total)
		if flagName != "" {
			fmt.Fprintf(w, " Use -%s NEXT_PAGE_TOKEN and/or -limit N to see more.", flagName)
		}
		fmt.Fprintln(w)
	}
}

func yesNo(b bool) string {
	if b {
		return "yes"
	}
	return "no"
}

func firstLine(s string) string {
	if before, _, ok := strings.Cut(s, "\n"); ok {
		return before
	}
	return s
}
