// 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 (
	"cmd/internal/cov"
	"cmd/internal/pkgpattern"
	"flag"
	"fmt"
	"os"
	"runtime"
	"runtime/pprof"
	"strings"
)

var verbflag = flag.Int("v", 0, "Verbose trace output level")
var hflag = flag.Bool("h", false, "Panic on fatal errors (for stack trace)")
var hwflag = flag.Bool("hw", false, "Panic on warnings (for stack trace)")
var indirsflag = flag.String("i", "", "Input dirs to examine (comma separated)")
var pkgpatflag = flag.String("pkg", "", "Restrict output to package(s) matching specified package pattern.")
var cpuprofileflag = flag.String("cpuprofile", "", "Write CPU profile to specified file")
var memprofileflag = flag.String("memprofile", "", "Write memory profile to specified file")
var memprofilerateflag = flag.Int("memprofilerate", 0, "Set memprofile sampling rate to value")

var matchpkg func(name string) bool

var atExitFuncs []func()

func atExit(f func()) {
	atExitFuncs = append(atExitFuncs, f)
}

func Exit(code int) {
	for i := len(atExitFuncs) - 1; i >= 0; i-- {
		f := atExitFuncs[i]
		atExitFuncs = atExitFuncs[:i]
		f()
	}
	os.Exit(code)
}

func dbgtrace(vlevel int, s string, a ...interface{}) {
	if *verbflag >= vlevel {
		fmt.Printf(s, a...)
		fmt.Printf("\n")
	}
}

func warn(s string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, "warning: ")
	fmt.Fprintf(os.Stderr, s, a...)
	fmt.Fprintf(os.Stderr, "\n")
	if *hwflag {
		panic("unexpected warning")
	}
}

func fatal(s string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, "error: ")
	fmt.Fprintf(os.Stderr, s, a...)
	fmt.Fprintf(os.Stderr, "\n")
	if *hflag {
		panic("fatal error")
	}
	Exit(1)
}

func usage(msg string) {
	if len(msg) > 0 {
		fmt.Fprintf(os.Stderr, "error: %s\n", msg)
	}
	fmt.Fprintf(os.Stderr, "usage: go tool covdata [command]\n")
	fmt.Fprintf(os.Stderr, `
Commands are:

textfmt     convert coverage data to textual format
percent     output total percentage of statements covered
pkglist     output list of package import paths
func        output coverage profile information for each function
merge       merge data files together
subtract    subtract one set of data files from another set
intersect   generate intersection of two sets of data files
debugdump   dump data in human-readable format for debugging purposes
`)
	fmt.Fprintf(os.Stderr, "\nFor help on a specific subcommand, try:\n")
	fmt.Fprintf(os.Stderr, "\ngo tool covdata <cmd> -help\n")
	Exit(2)
}

type covOperation interface {
	cov.CovDataVisitor
	Setup()
	Usage(string)
}

// Modes of operation.
const (
	funcMode      = "func"
	mergeMode     = "merge"
	intersectMode = "intersect"
	subtractMode  = "subtract"
	percentMode   = "percent"
	pkglistMode   = "pkglist"
	textfmtMode   = "textfmt"
	debugDumpMode = "debugdump"
)

func main() {
	// First argument should be mode/subcommand.
	if len(os.Args) < 2 {
		usage("missing command selector")
	}

	// Select mode
	var op covOperation
	cmd := os.Args[1]
	switch cmd {
	case mergeMode:
		op = makeMergeOp()
	case debugDumpMode:
		op = makeDumpOp(debugDumpMode)
	case textfmtMode:
		op = makeDumpOp(textfmtMode)
	case percentMode:
		op = makeDumpOp(percentMode)
	case funcMode:
		op = makeDumpOp(funcMode)
	case pkglistMode:
		op = makeDumpOp(pkglistMode)
	case subtractMode:
		op = makeSubtractIntersectOp(subtractMode)
	case intersectMode:
		op = makeSubtractIntersectOp(intersectMode)
	default:
		usage(fmt.Sprintf("unknown command selector %q", cmd))
	}

	// Edit out command selector, then parse flags.
	os.Args = append(os.Args[:1], os.Args[2:]...)
	flag.Usage = func() {
		op.Usage("")
	}
	flag.Parse()

	// Mode-independent flag setup
	dbgtrace(1, "starting mode-independent setup")
	if flag.NArg() != 0 {
		op.Usage("unknown extra arguments")
	}
	if *pkgpatflag != "" {
		pats := strings.Split(*pkgpatflag, ",")
		matchers := []func(name string) bool{}
		for _, p := range pats {
			if p == "" {
				continue
			}
			f := pkgpattern.MatchSimplePattern(p)
			matchers = append(matchers, f)
		}
		matchpkg = func(name string) bool {
			for _, f := range matchers {
				if f(name) {
					return true
				}
			}
			return false
		}
	}
	if *cpuprofileflag != "" {
		f, err := os.Create(*cpuprofileflag)
		if err != nil {
			fatal("%v", err)
		}
		if err := pprof.StartCPUProfile(f); err != nil {
			fatal("%v", err)
		}
		atExit(pprof.StopCPUProfile)
	}
	if *memprofileflag != "" {
		if *memprofilerateflag != 0 {
			runtime.MemProfileRate = *memprofilerateflag
		}
		f, err := os.Create(*memprofileflag)
		if err != nil {
			fatal("%v", err)
		}
		atExit(func() {
			runtime.GC()
			const writeLegacyFormat = 1
			if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
				fatal("%v", err)
			}
		})
	} else {
		// Not doing memory profiling; disable it entirely.
		runtime.MemProfileRate = 0
	}

	// Mode-dependent setup.
	op.Setup()

	// ... off and running now.
	dbgtrace(1, "starting perform")

	indirs := strings.Split(*indirsflag, ",")
	vis := cov.CovDataVisitor(op)
	var flags cov.CovDataReaderFlags
	if *hflag {
		flags |= cov.PanicOnError
	}
	if *hwflag {
		flags |= cov.PanicOnWarning
	}
	reader := cov.MakeCovDataReader(vis, indirs, *verbflag, flags, matchpkg)
	st := 0
	if err := reader.Visit(); err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		st = 1
	}
	dbgtrace(1, "leaving main")
	Exit(st)
}
