// Copyright 2015 The Vanadium 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 vtrace

import (
	"fmt"
	"log"
	"path/filepath"
	"runtime"
	"v.io/v23/context"
)

const (
	initialMaxStackBufSize = 128 * 1024
)

type VTraceLogger struct{}

func (*VTraceLogger) InfoDepth(ctx *context.T, depth int, args ...interface{}) {
	log.Println(args)
	span := getSpan(ctx)
	if span == nil {
		return
	}
	file, line := computeFileAndLine(depth + 1)
	output := fmt.Sprintf("%s:%d] %s", file, line, fmt.Sprint(args...))
	span.Annotate(output)
}

func (*VTraceLogger) InfoStack(ctx *context.T, all bool) {
	span := getSpan(ctx)
	if span == nil {
		return
	}

	span.Annotate(printStack(all))
}

func computeFileAndLine(depth int) (file string, line int) {
	var ok bool
	_, file, line, ok = runtime.Caller(depth + 1)
	if !ok {
		file = "???"
		line = 1
	} else {
		file = filepath.Base(file)
	}
	return
}

func printStack(all bool) string {
	n := initialMaxStackBufSize
	trace := make([]byte, n)
	nbytes := runtime.Stack(trace, all)
	if nbytes < len(trace) {
		return string(trace[:nbytes])
	}
	return string(trace)
}

func (*VTraceLogger) VDepth(ctx *context.T, depth int, level int) bool {
	return GetVTraceLevel(ctx) >= level
}

func (v *VTraceLogger) VIDepth(ctx *context.T, depth int, level int) context.ContextLogger {
	// InfoStack logs the current goroutine's stack if the all parameter
	// is false, or the stacks of all goroutine{
	if v.VDepth(ctx, depth, level) {
		return v
	}
	return nil
}
