// Copyright 2009 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.

// Debug arguments, set by -d flag.

package base

import (
	"fmt"
	"log"
	"os"
	"reflect"
	"strconv"
	"strings"

	"cmd/internal/objabi"
)

// Debug holds the parsed debugging configuration values.
var Debug = DebugFlags{
	Fieldtrack: &objabi.Fieldtrack_enabled,
}

// DebugFlags defines the debugging configuration values (see var Debug).
// Each struct field is a different value, named for the lower-case of the field name.
// Each field must be an int or string and must have a `help` struct tag.
//
// The -d option takes a comma-separated list of settings.
// Each setting is name=value; for ints, name is short for name=1.
type DebugFlags struct {
	Append               int    `help:"print information about append compilation"`
	Checkptr             int    `help:"instrument unsafe pointer conversions"`
	Closure              int    `help:"print information about closure compilation"`
	DclStack             int    `help:"run internal dclstack check"`
	Defer                int    `help:"print information about defer compilation"`
	DisableNil           int    `help:"disable nil checks"`
	DumpPtrs             int    `help:"show Node pointers values in dump output"`
	DwarfInl             int    `help:"print information about DWARF inlined function creation"`
	Export               int    `help:"print export data"`
	Fieldtrack           *int   `help:"enable field tracking"`
	GCProg               int    `help:"print dump of GC programs"`
	InlFuncsWithClosures int    `help:"allow functions with closures to be inlined"`
	Libfuzzer            int    `help:"enable coverage instrumentation for libfuzzer"`
	LocationLists        int    `help:"print information about DWARF location list creation"`
	Nil                  int    `help:"print information about nil checks"`
	PCTab                string `help:"print named pc-value table"`
	Panic                int    `help:"show all compiler panics"`
	Slice                int    `help:"print information about slice compilation"`
	SoftFloat            int    `help:"force compiler to emit soft-float code"`
	TypeAssert           int    `help:"print information about type assertion inlining"`
	TypecheckInl         int    `help:"eager typechecking of inline function bodies"`
	WB                   int    `help:"print information about write barriers"`
	ABIWrap              int    `help:"print information about ABI wrapper generation"`

	any bool // set when any of the values have been set
}

// Any reports whether any of the debug flags have been set.
func (d *DebugFlags) Any() bool { return d.any }

type debugField struct {
	name string
	help string
	val  interface{} // *int or *string
}

var debugTab []debugField

func init() {
	v := reflect.ValueOf(&Debug).Elem()
	t := v.Type()
	for i := 0; i < t.NumField(); i++ {
		f := t.Field(i)
		if f.Name == "any" {
			continue
		}
		name := strings.ToLower(f.Name)
		help := f.Tag.Get("help")
		if help == "" {
			panic(fmt.Sprintf("base.Debug.%s is missing help text", f.Name))
		}
		ptr := v.Field(i).Addr().Interface()
		switch ptr.(type) {
		default:
			panic(fmt.Sprintf("base.Debug.%s has invalid type %v (must be int or string)", f.Name, f.Type))
		case *int, *string:
			// ok
		case **int:
			ptr = *ptr.(**int) // record the *int itself
		}
		debugTab = append(debugTab, debugField{name, help, ptr})
	}
}

// DebugSSA is called to set a -d ssa/... option.
// If nil, those options are reported as invalid options.
// If DebugSSA returns a non-empty string, that text is reported as a compiler error.
var DebugSSA func(phase, flag string, val int, valString string) string

// parseDebug parses the -d debug string argument.
func parseDebug(debugstr string) {
	// parse -d argument
	if debugstr == "" {
		return
	}
	Debug.any = true
Split:
	for _, name := range strings.Split(debugstr, ",") {
		if name == "" {
			continue
		}
		// display help about the -d option itself and quit
		if name == "help" {
			fmt.Print(debugHelpHeader)
			maxLen := len("ssa/help")
			for _, t := range debugTab {
				if len(t.name) > maxLen {
					maxLen = len(t.name)
				}
			}
			for _, t := range debugTab {
				fmt.Printf("\t%-*s\t%s\n", maxLen, t.name, t.help)
			}
			// ssa options have their own help
			fmt.Printf("\t%-*s\t%s\n", maxLen, "ssa/help", "print help about SSA debugging")
			fmt.Print(debugHelpFooter)
			os.Exit(0)
		}
		val, valstring, haveInt := 1, "", true
		if i := strings.IndexAny(name, "=:"); i >= 0 {
			var err error
			name, valstring = name[:i], name[i+1:]
			val, err = strconv.Atoi(valstring)
			if err != nil {
				val, haveInt = 1, false
			}
		}
		for _, t := range debugTab {
			if t.name != name {
				continue
			}
			switch vp := t.val.(type) {
			case nil:
				// Ignore
			case *string:
				*vp = valstring
			case *int:
				if !haveInt {
					log.Fatalf("invalid debug value %v", name)
				}
				*vp = val
			default:
				panic("bad debugtab type")
			}
			continue Split
		}
		// special case for ssa for now
		if DebugSSA != nil && strings.HasPrefix(name, "ssa/") {
			// expect form ssa/phase/flag
			// e.g. -d=ssa/generic_cse/time
			// _ in phase name also matches space
			phase := name[4:]
			flag := "debug" // default flag is debug
			if i := strings.Index(phase, "/"); i >= 0 {
				flag = phase[i+1:]
				phase = phase[:i]
			}
			err := DebugSSA(phase, flag, val, valstring)
			if err != "" {
				log.Fatalf(err)
			}
			continue Split
		}
		log.Fatalf("unknown debug key -d %s\n", name)
	}
}

const debugHelpHeader = `usage: -d arg[,arg]* and arg is <key>[=<value>]

<key> is one of:

`

const debugHelpFooter = `
<value> is key-specific.

Key "checkptr" supports values:
	"0": instrumentation disabled
	"1": conversions involving unsafe.Pointer are instrumented
	"2": conversions to unsafe.Pointer force heap allocation

Key "pctab" supports values:
	"pctospadj", "pctofile", "pctoline", "pctoinline", "pctopcdata"
`
