package logger

import (
	"os"

	"github.com/davecgh/go-spew/spew"
	"github.com/op/go-logging"
)

// Log is global logger
var Log = logging.MustGetLogger("myLogger")
var logBackendLeveled logging.LeveledBackend

var Prefix = ""

// SetLogLevel sets log level for global logger (debug, info, notice, warning, error)
func SetLogLevel(level string) {
	logBackendLevel := logging.INFO
	switch level {
	case "debug":
		logBackendLevel = logging.DEBUG
		break

	case "info":
		logBackendLevel = logging.INFO
		break

	case "notice":
		logBackendLevel = logging.NOTICE
		break

	case "warning":
		logBackendLevel = logging.WARNING
		break

	case "error":
		logBackendLevel = logging.ERROR
		break

	}

	logBackendLeveled.SetLevel(logBackendLevel, "")
}

// configureLogger sets logger backend and level
func configureLogger() {
	logBackend := logging.NewLogBackend(os.Stderr, "", 0)
	logBackendFormatter := logging.NewBackendFormatter(logBackend, logging.MustStringFormatter(
		`%{color}%{time:2006-01-02 15:04:05.000} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
	))
	logBackendLeveled = logging.AddModuleLevel(logBackendFormatter)
	logBackendLeveled.SetLevel(logging.NOTICE, "")
	logging.SetBackend(logBackendLeveled)
}

func init() {
	spew.Config.DisablePointerAddresses = true
	spew.Config.DisableCapacities = true
	spew.Config.DisableMethods = true
	spew.Config.DisablePointerMethods = true
	configureLogger()
}

func prefix() string {
	return Prefix
}

// D is shorthand for Debugf
func D(format string, args ...interface{}) {
	Log.Debugf(prefix()+format, args...)
}

// I is shorthand for Infof
func I(format string, args ...interface{}) {
	Log.Infof(prefix()+format, args...)
}

// N is shorthand for Noticef
func N(format string, args ...interface{}) {
	Log.Noticef(prefix()+format, args...)
}

// W is shorthand for Warningf
func W(format string, args ...interface{}) {
	Log.Warningf(prefix()+format, args...)
}

// E is shorthand for Errorf
func E(format string, args ...interface{}) {
	Log.Errorf(prefix()+format, args...)
}

// P is shorthand for Panicf
func P(format string, args ...interface{}) {
	Log.Panicf(prefix()+format, args...)
}

// Eerr is shorthand for
// if err != nil {
//   Log.Errorf(...)
// }
func Eerr(err error, format string, args ...interface{}) {
	if err != nil {
		args = append(args, err)
		Log.Errorf(prefix()+format+" (Error: %s)", args...)
	}
}

// Eexit is shorthand for
// if err != nil {
//   Log.Errorf(...)
//	 os.Exit(1)
// }
func Eexit(err error, format string, args ...interface{}) {
	Eerr(err, format, args...)
	if err != nil {
		os.Exit(1)
	}
}

// Exit is shorthand for
//   Log.Errorf(...)
//	 os.Exit(1)
func Exit(format string, args ...interface{}) {
	E(format, args...)
	os.Exit(1)
}

// Perr is shorthand for
// if err != nil {
//   Log.Panicf(...)
// }
func Perr(err error, format string, args ...interface{}) {
	if err != nil {
		args = append(args, err)
		Log.Panicf(prefix()+format+" (Error: %s)", args...)
	}
}
