package log

import (
	"fmt"
	"os"
	"strconv"
	"strings"
	"time"
)

const LEVEL_DEBUG = 0
const LEVEL_INFO = 1
const LEVEL_WARNING = 2
const LEVEL_ERROR = 3
const LEVEL_FATAL = 4

var logLevel = 0

// exported functions
func SetLogLevel(level int) {
	logLevel = level
}

func Debug(message string, extras ...string) {
	DebugTimed(message, -1, extras...)
}

func DebugTimed(message string, timestamp int64, extras ...string) {
	trace(LEVEL_DEBUG, timestamp, message, extras...)
}

func Info(message string, extras ...string) {
	InfoTimed(message, -1, extras...)
}

func InfoTimed(message string, timestamp int64, extras ...string) {
	trace(LEVEL_INFO, timestamp, message, extras...)
}

func Warning(message string, extras ...string) {
	WarningTimed(message, -1, extras...)
}

func WarningTimed(message string, timestamp int64, extras ...string) {
	trace(LEVEL_WARNING, timestamp, message, extras...)
}

func Error(message string, extras ...string) {
	ErrorTimed(message, -1, extras...)
}

func ErrorTimed(message string, timestamp int64, extras ...string) {
	trace(LEVEL_ERROR, -1, message, extras...)
}

func Fatal(message string, extras ...string) {
	FatalTimed(message, -1, extras...)
}

func FatalTimed(message string, timestamp int64, extras ...string) {
	trace(LEVEL_FATAL, timestamp, message, extras...)
	trace(LEVEL_FATAL, -1, "exiting...")
	os.Exit(1)
}

// unexported functions
func trace(level int, timestamp int64, message string, extras ...string) {
	if len(message) == 0 || level < logLevel {
		return
	}
	suffix := strings.Join(extras, " | ")
	if len(suffix) > 0 {
		message += " (" + suffix + ")"
	}
	if timestamp >= 0 {

		message += " [" + strconv.Itoa(int(time.Now().UnixMilli()-timestamp)) + "ms" + "]"
	}
	fmt.Println(buildLogMessage(getPrefixForLogLevel(level), message))
}

func getPrefixForLogLevel(level int) string {
	switch level {
	case LEVEL_FATAL:
		return "fatal"
	case LEVEL_ERROR:
		return "error"
	case LEVEL_WARNING:
		return "warning"
	case LEVEL_INFO:
		return "info"
	default:
		return "debug"
	}
}

func buildLogMessage(prefix string, message string) string {
	return "[" + prefix + "] > " + message
}
