// Copyright 2022 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 (
	"encoding/json"
	"fmt"
	"os"
	"sort"
	"strings"

	"golang.org/x/exp/maps"
	"golang.org/x/vuln/exp/govulncheck"
	"golang.org/x/vuln/internal"
	"golang.org/x/vuln/osv"
)

func printJSON(r *govulncheck.Result) error {
	b, err := json.MarshalIndent(r, "", "\t")
	if err != nil {
		return err
	}
	os.Stdout.Write(b)
	fmt.Println()
	return nil
}

const (
	labelWidth = 16
	lineLength = 55
)

func printText(r *govulncheck.Result, verbose, source bool) {
	// unaffected are (imported) OSVs none of
	// which vulnerabilities are called.
	var unaffected []*govulncheck.Vuln
	uniqueVulns := 0
	for _, v := range r.Vulns {
		if !source || v.IsCalled() {
			uniqueVulns++
		} else {
			// save arbitrary Vuln for informational message
			unaffected = append(unaffected, v)
		}
	}
	switch uniqueVulns {
	case 0:
		fmt.Println("No vulnerabilities found.")
	case 1:
		fmt.Println("Found 1 known vulnerability.")
	default:
		fmt.Printf("Found %d known vulnerabilities.\n", uniqueVulns)
	}

	idx := 0
	for _, v := range r.Vulns {
		for _, m := range v.Modules {
			for _, p := range m.Packages {
				// In Binary mode there are no call stacks.
				if source && len(p.CallStacks) == 0 {
					continue
				}
				fmt.Println()

				id := v.OSV.ID
				details := wrap(v.OSV.Details, 80-labelWidth)
				found := packageVersionString(p.Path, m.FoundVersion)
				fixed := packageVersionString(p.Path, m.FixedVersion)

				var stacksBuilder strings.Builder
				if source { // there are no call stacks in binary mode
					var stacks string
					if !verbose {
						stacks = defaultCallStacks(p.CallStacks)
					} else {
						stacks = verboseCallStacks(p.CallStacks)
					}
					if len(stacks) > 0 {
						stacksBuilder.WriteString(indent("\n\nCall stacks in your code:\n", 2))
						stacksBuilder.WriteString(indent(stacks, 6))
					}
				}
				printVulnerability(idx+1, id, details, stacksBuilder.String(), found, fixed, platforms(v.OSV))
				idx++
			}
		}
	}
	if len(unaffected) > 0 {
		fmt.Println()
		fmt.Println(informationalMessage)
		idx = 0
		for idx, un := range unaffected {
			// We pick random module and package info for
			// unaffected OSVs.
			m := un.Modules[0]
			p := m.Packages[0]
			found := packageVersionString(p.Path, m.FoundVersion)
			fixed := packageVersionString(p.Path, m.FixedVersion)
			fmt.Println()
			printVulnerability(idx+1, un.OSV.ID, un.OSV.Details, "", found, fixed, platforms(un.OSV))
		}
	}
}

func printVulnerability(idx int, id, details, callstack, found, fixed, platforms string) {
	if fixed == "" {
		fixed = "N/A"
	}
	if platforms != "" {
		platforms = "  Platforms: " + platforms + "\n"
	}
	fmt.Printf(`Vulnerability #%d: %s
%s%s
  Found in: %s
  Fixed in: %s
%s  More info: https://pkg.go.dev/vuln/%s
`, idx, id, indent(details, 2), callstack, found, fixed, platforms, id)
}

func defaultCallStacks(css []govulncheck.CallStack) string {
	var summaries []string
	for _, cs := range css {
		summaries = append(summaries, cs.Summary)
	}

	// Sort call stack summaries and get rid of duplicates.
	// Note that different call stacks can yield same summaries.
	if len(summaries) > 0 {
		sort.Strings(summaries)
		summaries = compact(summaries)
	}
	var b strings.Builder
	for _, s := range summaries {
		b.WriteString(s)
		b.WriteString("\n")
	}
	return b.String()
}

func verboseCallStacks(css []govulncheck.CallStack) string {
	// Display one full call stack for each vuln.
	i := 1
	var b strings.Builder
	for _, cs := range css {
		b.WriteString(fmt.Sprintf("#%d: for function %s\n", i, cs.Symbol))
		for _, e := range cs.Frames {
			b.WriteString(fmt.Sprintf("  %s\n", e.Name()))
			if pos := internal.AbsRelShorter(e.Pos()); pos != "" {
				b.WriteString(fmt.Sprintf("      %s\n", pos))
			}
		}
		i++
	}
	return b.String()
}

// platforms returns a string describing the GOOS/GOARCH pairs that the vuln affects.
// If it affects all of them, it returns the empty string.
func platforms(e *osv.Entry) string {
	platforms := map[string]bool{}
	for _, a := range e.Affected {
		for _, p := range a.EcosystemSpecific.Imports {
			for _, os := range p.GOOS {
				for _, arch := range p.GOARCH {
					platforms[os+"/"+arch] = true
				}
			}
		}
	}
	keys := maps.Keys(platforms)
	sort.Strings(keys)
	return strings.Join(keys, ", ")
}

// compact replaces consecutive runs of equal elements with a single copy.
// This is like the uniq command found on Unix.
// compact modifies the contents of the slice s; it does not create a new slice.
//
// Modified (generics removed) from exp/slices/slices.go.
func compact(s []string) []string {
	if len(s) == 0 {
		return s
	}
	i := 1
	last := s[0]
	for _, v := range s[1:] {
		if v != last {
			s[i] = v
			i++
			last = v
		}
	}
	return s[:i]
}

func packageVersionString(packagePath, version string) string {
	if version == "" {
		return ""
	}
	return fmt.Sprintf("%s@%s", packagePath, version)
}

// indent returns the output of prefixing n spaces to s at every line break,
// except for empty lines. See TestIndent for examples.
func indent(s string, n int) string {
	b := []byte(s)
	var result []byte
	shouldAppend := true
	prefix := strings.Repeat(" ", n)
	for _, c := range b {
		if shouldAppend && c != '\n' {
			result = append(result, prefix...)
		}
		result = append(result, c)
		shouldAppend = c == '\n'
	}
	return string(result)
}
