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