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

// This file contains functions and apis to support the "go tool
// covdata" sub-commands that relate to dumping text format summaries
// and reports: "pkglist", "func",  "debugdump", "percent", and
// "textfmt".

import (
	"flag"
	"fmt"
	"internal/coverage"
	"internal/coverage/calloc"
	"internal/coverage/cformat"
	"internal/coverage/cmerge"
	"internal/coverage/decodecounter"
	"internal/coverage/decodemeta"
	"internal/coverage/pods"
	"os"
	"sort"
	"strings"
)

var textfmtoutflag *string
var liveflag *bool

func makeDumpOp(cmd string) covOperation {
	if cmd == textfmtMode || cmd == percentMode {
		textfmtoutflag = flag.String("o", "", "Output text format to file")
	}
	if cmd == debugDumpMode {
		liveflag = flag.Bool("live", false, "Select only live (executed) functions for dump output.")
	}
	d := &dstate{
		cmd: cmd,
		cm:  &cmerge.Merger{},
	}
	if d.cmd == pkglistMode {
		d.pkgpaths = make(map[string]struct{})
	}
	return d
}

// dstate encapsulates state and provides methods for implementing
// various dump operations. Specifically, dstate implements the
// CovDataVisitor interface, and is designed to be used in
// concert with the CovDataReader utility, which abstracts away most
// of the grubby details of reading coverage data files.
type dstate struct {
	// for batch allocation of counter arrays
	calloc.BatchCounterAlloc

	// counter merging state + methods
	cm *cmerge.Merger

	// counter data formatting helper
	format *cformat.Formatter

	// 'mm' stores values read from a counter data file; the pkfunc key
	// is a pkgid/funcid pair that uniquely identifies a function in
	// instrumented application.
	mm map[pkfunc]decodecounter.FuncPayload

	// pkm maps package ID to the number of functions in the package
	// with that ID. It is used to report inconsistencies in counter
	// data (for example, a counter data entry with pkgid=N funcid=10
	// where package N only has 3 functions).
	pkm map[uint32]uint32

	// pkgpaths records all package import paths encountered while
	// visiting coverage data files (used to implement the "pkglist"
	// subcommand).
	pkgpaths map[string]struct{}

	// Current package name and import path.
	pkgName       string
	pkgImportPath string

	// Module path for current package (may be empty).
	modulePath string

	// Dump subcommand (ex: "textfmt", "debugdump", etc).
	cmd string

	// File to which we will write text format output, if enabled.
	textfmtoutf *os.File

	// Total and covered statements (used by "debugdump" subcommand).
	totalStmts, coveredStmts int

	// Records whether preamble has been emitted for current pkg
	// (used when in "debugdump" mode)
	preambleEmitted bool
}

func (d *dstate) Usage(msg string) {
	if len(msg) > 0 {
		fmt.Fprintf(os.Stderr, "error: %s\n", msg)
	}
	fmt.Fprintf(os.Stderr, "usage: go tool covdata %s -i=<directories>\n\n", d.cmd)
	flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, "\nExamples:\n\n")
	switch d.cmd {
	case pkglistMode:
		fmt.Fprintf(os.Stderr, "  go tool covdata pkglist -i=dir1,dir2\n\n")
		fmt.Fprintf(os.Stderr, "  \treads coverage data files from dir1+dirs2\n")
		fmt.Fprintf(os.Stderr, "  \tand writes out a list of the import paths\n")
		fmt.Fprintf(os.Stderr, "  \tof all compiled packages.\n")
	case textfmtMode:
		fmt.Fprintf(os.Stderr, "  go tool covdata textfmt -i=dir1,dir2 -o=out.txt\n\n")
		fmt.Fprintf(os.Stderr, "  \tmerges data from input directories dir1+dir2\n")
		fmt.Fprintf(os.Stderr, "  \tand emits text format into file 'out.txt'\n")
	case percentMode:
		fmt.Fprintf(os.Stderr, "  go tool covdata percent -i=dir1,dir2\n\n")
		fmt.Fprintf(os.Stderr, "  \tmerges data from input directories dir1+dir2\n")
		fmt.Fprintf(os.Stderr, "  \tand emits percentage of statements covered\n\n")
	case funcMode:
		fmt.Fprintf(os.Stderr, "  go tool covdata func -i=dir1,dir2\n\n")
		fmt.Fprintf(os.Stderr, "  \treads coverage data files from dir1+dirs2\n")
		fmt.Fprintf(os.Stderr, "  \tand writes out coverage profile data for\n")
		fmt.Fprintf(os.Stderr, "  \teach function.\n")
	case debugDumpMode:
		fmt.Fprintf(os.Stderr, "  go tool covdata debugdump [flags] -i=dir1,dir2\n\n")
		fmt.Fprintf(os.Stderr, "  \treads coverage data from dir1+dir2 and dumps\n")
		fmt.Fprintf(os.Stderr, "  \tcontents in human-readable form to stdout, for\n")
		fmt.Fprintf(os.Stderr, "  \tdebugging purposes.\n")
	default:
		panic("unexpected")
	}
	Exit(2)
}

// Setup is called once at program startup time to vet flag values
// and do any necessary setup operations.
func (d *dstate) Setup() {
	if *indirsflag == "" {
		d.Usage("select input directories with '-i' option")
	}
	if d.cmd == textfmtMode || (d.cmd == percentMode && *textfmtoutflag != "") {
		if *textfmtoutflag == "" {
			d.Usage("select output file name with '-o' option")
		}
		var err error
		d.textfmtoutf, err = os.Create(*textfmtoutflag)
		if err != nil {
			d.Usage(fmt.Sprintf("unable to open textfmt output file %q: %v", *textfmtoutflag, err))
		}
	}
	if d.cmd == debugDumpMode {
		fmt.Printf("/* WARNING: the format of this dump is not stable and is\n")
		fmt.Printf(" * expected to change from one Go release to the next.\n")
		fmt.Printf(" *\n")
		fmt.Printf(" * produced by:\n")
		args := append([]string{os.Args[0]}, debugDumpMode)
		args = append(args, os.Args[1:]...)
		fmt.Printf(" *\t%s\n", strings.Join(args, " "))
		fmt.Printf(" */\n")
	}
}

func (d *dstate) BeginPod(p pods.Pod) {
	d.mm = make(map[pkfunc]decodecounter.FuncPayload)
}

func (d *dstate) EndPod(p pods.Pod) {
	if d.cmd == debugDumpMode {
		d.cm.ResetModeAndGranularity()
	}
}

func (d *dstate) BeginCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
	dbgtrace(2, "visit counter data file %s dirIdx %d", cdf, dirIdx)
	if d.cmd == debugDumpMode {
		fmt.Printf("data file %s", cdf)
		if cdr.Goos() != "" {
			fmt.Printf(" GOOS=%s", cdr.Goos())
		}
		if cdr.Goarch() != "" {
			fmt.Printf(" GOARCH=%s", cdr.Goarch())
		}
		if len(cdr.OsArgs()) != 0 {
			fmt.Printf("  program args: %+v\n", cdr.OsArgs())
		}
		fmt.Printf("\n")
	}
}

func (d *dstate) EndCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
}

func (d *dstate) VisitFuncCounterData(data decodecounter.FuncPayload) {
	if nf, ok := d.pkm[data.PkgIdx]; !ok || data.FuncIdx > nf {
		warn("func payload inconsistency: id [p=%d,f=%d] nf=%d len(ctrs)=%d in VisitFuncCounterData, ignored", data.PkgIdx, data.FuncIdx, nf, len(data.Counters))
		return
	}
	key := pkfunc{pk: data.PkgIdx, fcn: data.FuncIdx}
	val, found := d.mm[key]

	dbgtrace(5, "ctr visit pk=%d fid=%d found=%v len(val.ctrs)=%d len(data.ctrs)=%d", data.PkgIdx, data.FuncIdx, found, len(val.Counters), len(data.Counters))

	if len(val.Counters) < len(data.Counters) {
		t := val.Counters
		val.Counters = d.AllocateCounters(len(data.Counters))
		copy(val.Counters, t)
	}
	err, overflow := d.cm.MergeCounters(val.Counters, data.Counters)
	if err != nil {
		fatal("%v", err)
	}
	if overflow {
		warn("uint32 overflow during counter merge")
	}
	d.mm[key] = val
}

func (d *dstate) EndCounters() {
}

func (d *dstate) VisitMetaDataFile(mdf string, mfr *decodemeta.CoverageMetaFileReader) {
	newgran := mfr.CounterGranularity()
	newmode := mfr.CounterMode()
	if err := d.cm.SetModeAndGranularity(mdf, newmode, newgran); err != nil {
		fatal("%v", err)
	}
	if d.cmd == debugDumpMode {
		fmt.Printf("Cover mode: %s\n", newmode.String())
		fmt.Printf("Cover granularity: %s\n", newgran.String())
	}
	if d.format == nil {
		d.format = cformat.NewFormatter(mfr.CounterMode())
	}

	// To provide an additional layer of checking when reading counter
	// data, walk the meta-data file to determine the set of legal
	// package/function combinations. This will help catch bugs in the
	// counter file reader.
	d.pkm = make(map[uint32]uint32)
	np := uint32(mfr.NumPackages())
	payload := []byte{}
	for pkIdx := uint32(0); pkIdx < np; pkIdx++ {
		var pd *decodemeta.CoverageMetaDataDecoder
		var err error
		pd, payload, err = mfr.GetPackageDecoder(pkIdx, payload)
		if err != nil {
			fatal("reading pkg %d from meta-file %s: %s", pkIdx, mdf, err)
		}
		d.pkm[pkIdx] = pd.NumFuncs()
	}
}

func (d *dstate) BeginPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {
	d.preambleEmitted = false
	d.pkgImportPath = pd.PackagePath()
	d.pkgName = pd.PackageName()
	d.modulePath = pd.ModulePath()
	if d.cmd == pkglistMode {
		d.pkgpaths[d.pkgImportPath] = struct{}{}
	}
	d.format.SetPackage(pd.PackagePath())
}

func (d *dstate) EndPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {
}

func (d *dstate) VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc) {
	var counters []uint32
	key := pkfunc{pk: pkgIdx, fcn: fnIdx}
	v, haveCounters := d.mm[key]

	dbgtrace(5, "meta visit pk=%d fid=%d fname=%s file=%s found=%v len(val.ctrs)=%d", pkgIdx, fnIdx, fd.Funcname, fd.Srcfile, haveCounters, len(v.Counters))

	suppressOutput := false
	if haveCounters {
		counters = v.Counters
	} else if d.cmd == debugDumpMode && *liveflag {
		suppressOutput = true
	}

	if d.cmd == debugDumpMode && !suppressOutput {
		if !d.preambleEmitted {
			fmt.Printf("\nPackage path: %s\n", d.pkgImportPath)
			fmt.Printf("Package name: %s\n", d.pkgName)
			fmt.Printf("Module path: %s\n", d.modulePath)
			d.preambleEmitted = true
		}
		fmt.Printf("\nFunc: %s\n", fd.Funcname)
		fmt.Printf("Srcfile: %s\n", fd.Srcfile)
		fmt.Printf("Literal: %v\n", fd.Lit)
	}
	for i := 0; i < len(fd.Units); i++ {
		u := fd.Units[i]
		var count uint32
		if counters != nil {
			count = counters[i]
		}
		d.format.AddUnit(fd.Srcfile, fd.Funcname, fd.Lit, u, count)
		if d.cmd == debugDumpMode && !suppressOutput {
			fmt.Printf("%d: L%d:C%d -- L%d:C%d ",
				i, u.StLine, u.StCol, u.EnLine, u.EnCol)
			if u.Parent != 0 {
				fmt.Printf("Parent:%d = %d\n", u.Parent, count)
			} else {
				fmt.Printf("NS=%d = %d\n", u.NxStmts, count)
			}
		}
		d.totalStmts += int(u.NxStmts)
		if count != 0 {
			d.coveredStmts += int(u.NxStmts)
		}
	}
}

func (d *dstate) Finish() {
	// d.format maybe nil here if the specified input dir was empty.
	if d.format != nil {
		if d.cmd == percentMode {
			d.format.EmitPercent(os.Stdout, "", false)
		}
		if d.cmd == funcMode {
			d.format.EmitFuncs(os.Stdout)
		}
		if d.textfmtoutf != nil {
			if err := d.format.EmitTextual(d.textfmtoutf); err != nil {
				fatal("writing to %s: %v", *textfmtoutflag, err)
			}
		}
	}
	if d.textfmtoutf != nil {
		if err := d.textfmtoutf.Close(); err != nil {
			fatal("closing textfmt output file %s: %v", *textfmtoutflag, err)
		}
	}
	if d.cmd == debugDumpMode {
		fmt.Printf("totalStmts: %d coveredStmts: %d\n", d.totalStmts, d.coveredStmts)
	}
	if d.cmd == pkglistMode {
		pkgs := make([]string, 0, len(d.pkgpaths))
		for p := range d.pkgpaths {
			pkgs = append(pkgs, p)
		}
		sort.Strings(pkgs)
		for _, p := range pkgs {
			fmt.Printf("%s\n", p)
		}
	}
}
