//===- debug.go - debug info builder --------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This package builds LLVM debug info from go/* data structures.
//
//===----------------------------------------------------------------------===//

package debug

import (
	"debug/dwarf"
	"fmt"
	"go/token"
	"os"
	"strings"

	"llvm.org/llgo/third_party/gotools/go/ssa"
	"llvm.org/llgo/third_party/gotools/go/types"
	"llvm.org/llgo/third_party/gotools/go/types/typeutil"

	"llvm.org/llvm/bindings/go/llvm"
)

const (
	// non-standard debug metadata tags
	tagAutoVariable dwarf.Tag = 0x100
	tagArgVariable  dwarf.Tag = 0x101
)

type PrefixMap struct {
	Source, Replacement string
}

// DIBuilder builds debug metadata for Go programs.
type DIBuilder struct {
	// builder is the current builder; there is one per CU.
	builder    *llvm.DIBuilder
	module     llvm.Module
	files      map[*token.File]llvm.Metadata
	cu, fn, lb llvm.Metadata
	fnFile     string
	sizes      types.Sizes
	fset       *token.FileSet
	prefixMaps []PrefixMap
	types      typeutil.Map
	voidType   llvm.Metadata
}

// NewDIBuilder creates a new debug information builder.
func NewDIBuilder(sizes types.Sizes, module llvm.Module, fset *token.FileSet, prefixMaps []PrefixMap) *DIBuilder {
	var d DIBuilder
	d.module = module
	d.files = make(map[*token.File]llvm.Metadata)
	d.sizes = sizes
	d.fset = fset
	d.prefixMaps = prefixMaps
	d.builder = llvm.NewDIBuilder(d.module)
	d.cu = d.createCompileUnit()
	return &d
}

// Destroy destroys the DIBuilder.
func (d *DIBuilder) Destroy() {
	d.builder.Destroy()
}

func (d *DIBuilder) scope() llvm.Metadata {
	if d.lb.C != nil {
		return d.lb
	}
	if d.fn.C != nil {
		return d.fn
	}
	return d.cu
}

func (d *DIBuilder) remapFilePath(path string) string {
	for _, pm := range d.prefixMaps {
		if strings.HasPrefix(path, pm.Source) {
			return pm.Replacement + path[len(pm.Source):]
		}
	}
	return path
}

func (d *DIBuilder) getFile(file *token.File) llvm.Metadata {
	if diFile := d.files[file]; diFile.C != nil {
		return diFile
	}
	diFile := d.builder.CreateFile(d.remapFilePath(file.Name()), "")
	d.files[file] = diFile
	return diFile
}

// createCompileUnit creates and returns debug metadata for the compile
// unit as a whole, using the first file in the file set as a representative
// (the choice of file is arbitrary).
func (d *DIBuilder) createCompileUnit() llvm.Metadata {
	var file *token.File
	d.fset.Iterate(func(f *token.File) bool {
		file = f
		return false
	})
	dir, err := os.Getwd()
	if err != nil {
		panic("could not get current directory: " + err.Error())
	}
	return d.builder.CreateCompileUnit(llvm.DICompileUnit{
		Language: llvm.DW_LANG_Go,
		File:     d.remapFilePath(file.Name()),
		Dir:      dir,
		Producer: "llgo",
	})
}

// PushFunction creates debug metadata for the specified function,
// and pushes it onto the scope stack.
func (d *DIBuilder) PushFunction(fnptr llvm.Value, sig *types.Signature, pos token.Pos) {
	var diFile llvm.Metadata
	var line int
	if file := d.fset.File(pos); file != nil {
		d.fnFile = file.Name()
		diFile = d.getFile(file)
		line = file.Line(pos)
	}
	d.fn = d.builder.CreateFunction(d.scope(), llvm.DIFunction{
		Name:         fnptr.Name(), // TODO(axw) unmangled name?
		LinkageName:  fnptr.Name(),
		File:         diFile,
		Line:         line,
		Type:         d.DIType(sig),
		IsDefinition: true,
	})
	fnptr.SetSubprogram(d.fn)
}

// PopFunction pops the previously pushed function off the scope stack.
func (d *DIBuilder) PopFunction() {
	d.lb = llvm.Metadata{}
	d.fn = llvm.Metadata{}
	d.fnFile = ""
}

// Value creates an llvm.dbg.value call for the specified register value.
func (d *DIBuilder) Value(b llvm.Builder, v ssa.Value, llv llvm.Value, paramIndex int) {
	// TODO(axw)
}

// SetLocation sets the current debug location.
func (d *DIBuilder) SetLocation(b llvm.Builder, pos token.Pos) {
	position := d.fset.Position(pos)
	d.lb = llvm.Metadata{}
	if position.Filename != d.fnFile && position.Filename != "" {
		// This can happen rarely, e.g. in init functions.
		diFile := d.builder.CreateFile(d.remapFilePath(position.Filename), "")
		d.lb = d.builder.CreateLexicalBlockFile(d.scope(), diFile, 0)
	}
	b.SetCurrentDebugLocation(uint(position.Line), uint(position.Column), d.scope(), llvm.Metadata{})
}

// Finalize must be called after all compilation units are translated,
// generating the final debug metadata for the module.
func (d *DIBuilder) Finalize() {
	d.module.AddNamedMetadataOperand(
		"llvm.module.flags",
		llvm.GlobalContext().MDNode([]llvm.Metadata{
			llvm.ConstInt(llvm.Int32Type(), 2, false).ConstantAsMetadata(), // Warn on mismatch
			llvm.GlobalContext().MDString("Dwarf Version"),
			llvm.ConstInt(llvm.Int32Type(), 4, false).ConstantAsMetadata(),
		}),
	)
	d.module.AddNamedMetadataOperand(
		"llvm.module.flags",
		llvm.GlobalContext().MDNode([]llvm.Metadata{
			llvm.ConstInt(llvm.Int32Type(), 1, false).ConstantAsMetadata(), // Error on mismatch
			llvm.GlobalContext().MDString("Debug Info Version"),
			llvm.ConstInt(llvm.Int32Type(), 3, false).ConstantAsMetadata(),
		}),
	)
	d.builder.Finalize()
}

// DIType maps a Go type to DIType debug metadata value.
func (d *DIBuilder) DIType(t types.Type) llvm.Metadata {
	return d.typeDebugDescriptor(t, types.TypeString(nil, t))
}

func (d *DIBuilder) typeDebugDescriptor(t types.Type, name string) llvm.Metadata {
	// Signature needs to be handled specially, to preprocess
	// methods, moving the receiver to the parameter list.
	if t, ok := t.(*types.Signature); ok {
		return d.descriptorSignature(t, name)
	}
	if t == nil {
		if d.voidType.C == nil {
			d.voidType = d.builder.CreateBasicType(llvm.DIBasicType{Name: "void"})
		}
		return d.voidType
	}
	if dt, ok := d.types.At(t).(llvm.Metadata); ok {
		return dt
	}
	dt := d.descriptor(t, name)
	d.types.Set(t, dt)
	return dt
}

func (d *DIBuilder) descriptor(t types.Type, name string) llvm.Metadata {
	switch t := t.(type) {
	case *types.Basic:
		return d.descriptorBasic(t, name)
	case *types.Pointer:
		return d.descriptorPointer(t)
	case *types.Struct:
		return d.descriptorStruct(t, name)
	case *types.Named:
		return d.descriptorNamed(t)
	case *types.Array:
		return d.descriptorArray(t, name)
	case *types.Slice:
		return d.descriptorSlice(t, name)
	case *types.Map:
		return d.descriptorMap(t, name)
	case *types.Chan:
		return d.descriptorChan(t, name)
	case *types.Interface:
		return d.descriptorInterface(t, name)
	default:
		panic(fmt.Sprintf("unhandled type: %T", t))
	}
}

func (d *DIBuilder) descriptorBasic(t *types.Basic, name string) llvm.Metadata {
	switch t.Kind() {
	case types.String:
		return d.typeDebugDescriptor(types.NewStruct([]*types.Var{
			types.NewVar(0, nil, "ptr", types.NewPointer(types.Typ[types.Uint8])),
			types.NewVar(0, nil, "len", types.Typ[types.Int]),
		}, nil), name)
	case types.UnsafePointer:
		return d.builder.CreateBasicType(llvm.DIBasicType{
			Name:        name,
			SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
			Encoding:    llvm.DW_ATE_unsigned,
		})
	default:
		bt := llvm.DIBasicType{
			Name:        t.String(),
			SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
		}
		switch bi := t.Info(); {
		case bi&types.IsBoolean != 0:
			bt.Encoding = llvm.DW_ATE_boolean
		case bi&types.IsUnsigned != 0:
			bt.Encoding = llvm.DW_ATE_unsigned
		case bi&types.IsInteger != 0:
			bt.Encoding = llvm.DW_ATE_signed
		case bi&types.IsFloat != 0:
			bt.Encoding = llvm.DW_ATE_float
		case bi&types.IsComplex != 0:
			bt.Encoding = llvm.DW_ATE_imaginary_float
		case bi&types.IsUnsigned != 0:
			bt.Encoding = llvm.DW_ATE_unsigned
		default:
			panic(fmt.Sprintf("unhandled: %#v", t))
		}
		return d.builder.CreateBasicType(bt)
	}
}

func (d *DIBuilder) descriptorPointer(t *types.Pointer) llvm.Metadata {
	return d.builder.CreatePointerType(llvm.DIPointerType{
		Pointee:     d.DIType(t.Elem()),
		SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
		AlignInBits: uint32(d.sizes.Alignof(t) * 8),
	})
}

func (d *DIBuilder) descriptorStruct(t *types.Struct, name string) llvm.Metadata {
	fields := make([]*types.Var, t.NumFields())
	for i := range fields {
		fields[i] = t.Field(i)
	}
	offsets := d.sizes.Offsetsof(fields)
	members := make([]llvm.Metadata, len(fields))
	for i, f := range fields {
		// TODO(axw) file/line where member is defined.
		t := f.Type()
		members[i] = d.builder.CreateMemberType(d.cu, llvm.DIMemberType{
			Name:         f.Name(),
			Type:         d.DIType(t),
			SizeInBits:   uint64(d.sizes.Sizeof(t) * 8),
			AlignInBits:  uint32(d.sizes.Alignof(t) * 8),
			OffsetInBits: uint64(offsets[i] * 8),
		})
	}
	// TODO(axw) file/line where struct is defined.
	return d.builder.CreateStructType(d.cu, llvm.DIStructType{
		Name:        name,
		SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
		AlignInBits: uint32(d.sizes.Alignof(t) * 8),
		Elements:    members,
	})
}

func (d *DIBuilder) descriptorNamed(t *types.Named) llvm.Metadata {
	var diFile llvm.Metadata
	var line int
	if file := d.fset.File(t.Obj().Pos()); file != nil {
		line = file.Line(t.Obj().Pos())
		diFile = d.getFile(file)
	}

	// Create a placeholder for the named type, to terminate cycles.
	name := t.Obj().Name()
	placeholder := d.builder.CreateReplaceableCompositeType(d.scope(), llvm.DIReplaceableCompositeType{
		Tag:  dwarf.TagStructType,
		Name: name,
		File: diFile,
		Line: line,
	})
	d.types.Set(t, placeholder)

	typedef := d.builder.CreateTypedef(llvm.DITypedef{
		Type: d.DIType(t.Underlying()),
		Name: name,
		File: diFile,
		Line: line,
	})
	placeholder.ReplaceAllUsesWith(typedef)
	return typedef
}

func (d *DIBuilder) descriptorArray(t *types.Array, name string) llvm.Metadata {
	return d.builder.CreateArrayType(llvm.DIArrayType{
		SizeInBits:  uint64(d.sizes.Sizeof(t) * 8),
		AlignInBits: uint32(d.sizes.Alignof(t) * 8),
		ElementType: d.DIType(t.Elem()),
		Subscripts:  []llvm.DISubrange{{Count: t.Len()}},
	})
}

func (d *DIBuilder) descriptorSlice(t *types.Slice, name string) llvm.Metadata {
	sliceStruct := types.NewStruct([]*types.Var{
		types.NewVar(0, nil, "ptr", types.NewPointer(t.Elem())),
		types.NewVar(0, nil, "len", types.Typ[types.Int]),
		types.NewVar(0, nil, "cap", types.Typ[types.Int]),
	}, nil)
	return d.typeDebugDescriptor(sliceStruct, name)
}

func (d *DIBuilder) descriptorMap(t *types.Map, name string) llvm.Metadata {
	// FIXME: This should be DW_TAG_pointer_type to __go_map.
	return d.descriptorBasic(types.Typ[types.Uintptr], name)
}

func (d *DIBuilder) descriptorChan(t *types.Chan, name string) llvm.Metadata {
	// FIXME: This should be DW_TAG_pointer_type to __go_channel.
	return d.descriptorBasic(types.Typ[types.Uintptr], name)
}

func (d *DIBuilder) descriptorInterface(t *types.Interface, name string) llvm.Metadata {
	ifaceStruct := types.NewStruct([]*types.Var{
		types.NewVar(0, nil, "type", types.NewPointer(types.Typ[types.Uint8])),
		types.NewVar(0, nil, "data", types.NewPointer(types.Typ[types.Uint8])),
	}, nil)
	return d.typeDebugDescriptor(ifaceStruct, name)
}

func (d *DIBuilder) descriptorSignature(t *types.Signature, name string) llvm.Metadata {
	// If there's a receiver change the receiver to an
	// additional (first) parameter, and take the value of
	// the resulting signature instead.
	if recv := t.Recv(); recv != nil {
		params := t.Params()
		paramvars := make([]*types.Var, int(params.Len()+1))
		paramvars[0] = recv
		for i := 0; i < int(params.Len()); i++ {
			paramvars[i+1] = params.At(i)
		}
		params = types.NewTuple(paramvars...)
		t := types.NewSignature(nil, nil, params, t.Results(), t.Variadic())
		return d.typeDebugDescriptor(t, name)
	}
	if dt, ok := d.types.At(t).(llvm.Metadata); ok {
		return dt
	}

	var returnType llvm.Metadata
	results := t.Results()
	switch n := results.Len(); n {
	case 0:
		returnType = d.DIType(nil) // void
	case 1:
		returnType = d.DIType(results.At(0).Type())
	default:
		fields := make([]*types.Var, results.Len())
		for i := range fields {
			f := results.At(i)
			// Structs may not have multiple fields
			// with the same name, excepting "_".
			if f.Name() == "" {
				f = types.NewVar(f.Pos(), f.Pkg(), "_", f.Type())
			}
			fields[i] = f
		}
		returnType = d.typeDebugDescriptor(types.NewStruct(fields, nil), "")
	}

	var paramTypes []llvm.Metadata
	params := t.Params()
	if params != nil && params.Len() > 0 {
		paramTypes = make([]llvm.Metadata, params.Len()+1)
		paramTypes[0] = returnType
		for i := range paramTypes[1:] {
			paramTypes[i+1] = d.DIType(params.At(i).Type())
		}
	} else {
		paramTypes = []llvm.Metadata{returnType}
	}

	// TODO(axw) get position of type definition for File field
	return d.builder.CreateSubroutineType(llvm.DISubroutineType{
		Parameters: paramTypes,
	})
}
