package myth

import (
	"io"
	"log"
	"os"
)

// Logger logger
type Logger struct {
	logger *log.Logger
}

var (
	defLog *Logger
	defFP  *os.File
)

// NewDefaultLogger defult logger
func NewDefaultLogger(path string) (*Logger, error) {
	var err error
	fp := &os.File{}
	if fp, err = os.OpenFile(path, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666); err != nil {
		return nil, err
	}

	defLog = NewLogger(fp)
	defFP = fp

	return defLog, nil
}

// ReopenDefaultLogger re open default logger
func ReopenDefaultLogger(path string) (*Logger, error) {
	var err error
	fp := &os.File{}
	if fp, err = os.OpenFile(path, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666); err != nil {
		return nil, err
	}

	if defLog == nil {
		defLog = NewLogger(fp)
	}
	fpo := defFP
	defFP = fp
	defLog.logger = log.New(fp, "[INFO]", log.LstdFlags)
	fpo.Close()

	return defLog, nil
}

// CloseDefaultLogger close
func CloseDefaultLogger() error {
	return defFP.Close()
}

// LogDebug debug
func LogDebug(v ...interface{}) {
	defLog.logger.SetPrefix("[DEBUG]")
	defLog.logger.Println(v...)
}

// LogInfo info
func LogInfo(v ...interface{}) {
	defLog.logger.SetPrefix("[INFO]")
	defLog.logger.Println(v...)
}

// LogWarn warn
func LogWarn(v ...interface{}) {
	defLog.logger.SetPrefix("[Warn]")
	defLog.logger.Println(v...)
}

// LogErr err
func LogErr(v ...interface{}) {
	defLog.logger.SetPrefix("[Err]")
	defLog.logger.Println(v...)
}

// LogAlert alert
func LogAlert(v ...interface{}) {
	defLog.logger.SetPrefix("[Alert]")
	defLog.logger.Println(v...)
}

// NewLogger new logger
func NewLogger(out io.Writer) *Logger {
	logger := log.New(out, "[INFO]", log.Ldate|log.Ltime)
	return &Logger{logger: logger}
}

// Info log info
func (l *Logger) Info(v ...interface{}) {
	l.logger.SetPrefix("[INFO]")
	l.logger.Println(v...)
}

// Debug log debug
func (l *Logger) Debug(v ...interface{}) {
	l.logger.SetPrefix("[DEBUG]")
	l.logger.Println(v...)
}

// Warn log Warn
func (l *Logger) Warn(v ...interface{}) {
	l.logger.SetPrefix("[Warn]")
	l.logger.Println(v...)
}

// Err log Err
func (l *Logger) Err(v ...interface{}) {
	l.logger.SetPrefix("[Err]")
	l.logger.Println(v...)
}

// Alert log Alert
func (l *Logger) Alert(v ...interface{}) {
	l.logger.SetPrefix("[Alert]")
	l.logger.Println(v...)
}