// Copyright 2016 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package logging implements a gRPC glog.Logger implementation backed
// by a go.chromium.org/luci/common/logging Logger.
//
// The logger can be installed by calling Install.
package logging

import (
	"os"
	"runtime"
	"strings"

	"go.chromium.org/luci/common/logging"

	"google.golang.org/grpc/grpclog"
)

// Suppress is a sentinel logging level that instructs the logger to suppress
// all non-fatal logging output. This is NOT a valid logging.Level, and should
// not be used as such.
var Suppress = logging.Level(logging.Error + 1)

type grpcLogger struct {
	base   logging.Logger
	vLevel int
}

// Install installs a logger as the gRPC library's logger. The installation is
// not protected by a mutex, so this must be set somewhere that atomic access is
// guaranteed.
//
// A special logging level, "Suppress", can be provided to suppress all
// non-fatal logging output .
//
// gRPC V=level and error terminology translation is as follows:
// - V=0, ERROR (low verbosity) is logged at logging.ERROR level.
// - V=1, WARNING (medium verbosity) is logged at logging.WARNING level.
// - V=2, INFO (high verbosity) is logged at logging.DEBUG level.
func Install(base logging.Logger, level logging.Level) {
	grpclog.SetLoggerV2(&grpcLogger{
		base:   base,
		vLevel: translateLevel(level),
	})
}

func (gl *grpcLogger) Info(args ...interface{}) {
	if gl.V(2) {
		gl.base.LogCall(logging.Debug, 2, makeArgFormatString(args), args)
	}
}

func (gl *grpcLogger) Infof(format string, args ...interface{}) {
	if gl.V(2) {
		gl.base.LogCall(logging.Debug, 2, format, args)
	}
}

func (gl *grpcLogger) Infoln(args ...interface{}) {
	if gl.V(2) {
		gl.base.LogCall(logging.Debug, 2, makeArgFormatString(args), args)
	}
}

func (gl *grpcLogger) Warning(args ...interface{}) {
	if gl.V(1) {
		gl.base.LogCall(logging.Warning, 2, makeArgFormatString(args), args)
	}
}

func (gl *grpcLogger) Warningf(format string, args ...interface{}) {
	if gl.V(1) {
		gl.base.LogCall(logging.Warning, 2, format, args)
	}
}

func (gl *grpcLogger) Warningln(args ...interface{}) {
	if gl.V(1) {
		gl.base.LogCall(logging.Warning, 2, makeArgFormatString(args), args)
	}
}

func (gl *grpcLogger) Error(args ...interface{}) {
	if gl.V(0) {
		gl.base.LogCall(logging.Error, 2, makeArgFormatString(args), args)
	}
}

func (gl *grpcLogger) Errorf(format string, args ...interface{}) {
	if gl.V(0) {
		gl.base.LogCall(logging.Error, 2, format, args)
	}
}

func (gl *grpcLogger) Errorln(args ...interface{}) {
	if gl.V(0) {
		gl.base.LogCall(logging.Error, 2, makeArgFormatString(args), args)
	}
}

func (gl *grpcLogger) Fatal(args ...interface{}) {
	gl.base.LogCall(logging.Error, 2, makeArgFormatString(args), args)
	gl.logStackTraceAndDie()
}

func (gl *grpcLogger) Fatalf(format string, args ...interface{}) {
	gl.base.LogCall(logging.Error, 2, format, args)
	gl.logStackTraceAndDie()
}

func (gl *grpcLogger) Fatalln(args ...interface{}) {
	gl.base.LogCall(logging.Error, 2, makeArgFormatString(args), args)
	gl.logStackTraceAndDie()
}

func (gl *grpcLogger) V(l int) bool {
	return gl.vLevel >= l
}

func (gl *grpcLogger) logStackTraceAndDie() {
	gl.base.LogCall(logging.Error, 3, "Stack Trace:\n%s", []interface{}{stacks(true)})
	fatalExit()
}

// fatalExit is an operating system exit function used by "Fatal" logs. It is a
// variable here so it can be stubbed for testing, but will exit with a non-zero
// return code by default.
var fatalExit = func() {
	os.Exit(1)
}

// stacks is a wrapper for runtime.Stack that attempts to recover the data for
// all goroutines.
//
// This was copied from the glog library:
// https://github.com/golang/glog @ / 23def4e6c14b4da8ac2ed8007337bc5eb5007998
func stacks(all bool) []byte {
	// We don't know how big the traces are, so grow a few times if they don't fit.
	// Start large, though.
	n := 10000
	if all {
		n = 100000
	}
	var trace []byte
	for i := 0; i < 5; i++ {
		trace = make([]byte, n)
		nbytes := runtime.Stack(trace, all)
		if nbytes < len(trace) {
			return trace[:nbytes]
		}
		n *= 2
	}
	return trace
}

func makeArgFormatString(args []interface{}) string {
	if len(args) == 0 {
		return ""
	}
	return strings.TrimSuffix(strings.Repeat("%v ", len(args)), " ")
}

// translateLevel translates a "verbose level" to a logging level.
func translateLevel(l logging.Level) int {
	switch l {
	case Suppress:
		return -1
	case logging.Error:
		return 0
	case logging.Warning, logging.Info:
		return 1
	default:
		return 2
	}
}
