// 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 vlog

import (
	"github.com/cosmosnicolaou/llog"
)

// Info logs to the INFO log.
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
func Info(args ...interface{}) {
	Log.log.Print(llog.InfoLog, args...)
	Log.maybeFlush()
}

// Infof logs to the INFO log.
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
func Infof(format string, args ...interface{}) {
	Log.log.Printf(llog.InfoLog, format, args...)
	Log.maybeFlush()
}

// InfoStack logs the current goroutine's stack if the all parameter
// is false, or the stacks of all goroutines if it's true.
func InfoStack(all bool) {
	infoStack(Log, all)
}

// V returns true if the configured logging level is greater than or equal to its parameter
func V(level Level) bool {
	return Log.log.V(llog.Level(level))
}

// VI is like V, except that it returns an instance of the Info
// interface that will either log (if level >= the configured level)
// or discard its parameters. This allows for logger.VI(2).Info
// style usage.
func VI(level Level) InfoLog {
	if Log.log.V(llog.Level(level)) {
		return Log
	}
	return &discardInfo{}
}

// Flush flushes all pending log I/O.
func FlushLog() {
	Log.FlushLog()
}

// Error logs to the ERROR and INFO logs.
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
func Error(args ...interface{}) {
	Log.log.Print(llog.ErrorLog, args...)
	Log.maybeFlush()
}

// Errorf logs to the ERROR and INFO logs.
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
func Errorf(format string, args ...interface{}) {
	Log.log.Printf(llog.ErrorLog, format, args...)
	Log.maybeFlush()
}

// Fatal logs to the FATAL, ERROR and INFO logs,
// including a stack trace of all running goroutines, then calls os.Exit(255).
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
func Fatal(args ...interface{}) {
	Log.log.Print(llog.FatalLog, args...)
}

// Fatalf logs to the FATAL, ERROR and INFO logs,
// including a stack trace of all running goroutines, then calls os.Exit(255).
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
func Fatalf(format string, args ...interface{}) {
	Log.log.Printf(llog.FatalLog, format, args...)
}

// ConfigureLogging configures all future logging. Some options
// may not be usable if ConfigureLogging is called from an init function,
// in which case an error will be returned. The Configured error is
// returned if ConfigureLogger has already been called unless the
// OverridePriorConfiguration options is included.
func Configure(opts ...LoggingOpts) error {
	return Log.Configure(opts...)
}

// Stats returns stats on how many lines/bytes haven been written to
// this set of logs.
func Stats() LevelStats {
	return Log.Stats()
}

// Panic is equivalent to Error() followed by a call to panic().
func Panic(args ...interface{}) {
	Log.Panic(args...)
}

// Panicf is equivalent to Errorf() followed by a call to panic().
func Panicf(format string, args ...interface{}) {
	Log.Panicf(format, args...)
}
