package util

import (
	"fmt"
	"log"
	"os"
	"time"
)

const LogFileTimeNowFormat = "2006-1-2"
const LogLinePrefixTimeNowFormat = "2006-1-2 12:00:00"

var DebugPrefix = "[Debug] "
var InfoPrefix = "[Info] "
var ErrorPrefix = "[Error] "
var FatalPrefix = "[FATAL] "

var LogFileDirectory = "./"
var DefaultLogFilePrefix = LogFileDirectory + "cluster_migration"

var LogLinePrefix = "[" + time.Now().Format(LogLinePrefixTimeNowFormat) + "]"
var CurrentLogFile = ""
var Logger *SingleLogger

func LogfileName() string {
	return DefaultLogFilePrefix + "_" + time.Now().Format(LogFileTimeNowFormat) + ".log"
}

type SingleLogger struct {
	logger *log.Logger
}

func NewLogger(logFileName string) (*SingleLogger, error) {
	if len(logFileName) == 0 {
		if len(CurrentLogFile) == 0 {
			CurrentLogFile = LogfileName()
		}
		logFileName = CurrentLogFile
	}
	CurrentLogFile = logFileName

	logfile, err := os.OpenFile(CurrentLogFile, os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		return nil, err
	}

	Logger = &SingleLogger{
		logger: log.New(logfile, LogLinePrefix, 0)}

	return Logger, err
}

func (l *SingleLogger) Fatalf(format string, v ...any) {
	if v == nil {
		fmt.Printf(LogLinePrefix + FatalPrefix + format)
		l.logger.Printf(format)
	} else {
		fmt.Printf(LogLinePrefix+FatalPrefix+format, v)
		l.logger.Printf(format, v)
	}
	os.Exit(-1)
}

func (l *SingleLogger) Errorf(format string, v ...any) {
	if v == nil {
		fmt.Printf(LogLinePrefix + ErrorPrefix + format)
		l.logger.Printf(format)
	} else {
		fmt.Printf(LogLinePrefix+ErrorPrefix+format, v)
		l.logger.Printf(format, v)
	}
}

func (l *SingleLogger) Printf(format string, v ...any) {
	if v == nil {
		fmt.Printf(LogLinePrefix + InfoPrefix + format)
		l.logger.Printf(format)
	} else {
		fmt.Printf(LogLinePrefix+InfoPrefix+format, v)
		l.logger.Printf(format, v)
	}
}

func (l *SingleLogger) Debugf(format string, v ...any) {
	if v == nil {
		fmt.Printf(LogLinePrefix + DebugPrefix + format)
		l.logger.Printf(format)
	} else {
		fmt.Printf(LogLinePrefix+DebugPrefix+format, v)
		l.logger.Printf(format, v)
	}
}
