package golog

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"time"

	log "github.com/go-playground/log"
)

var logLevelsArray = []log.Level{log.DebugLevel,
	log.TraceLevel,
	log.InfoLevel,
	log.NoticeLevel,
	log.WarnLevel,
	log.ErrorLevel,
	log.PanicLevel,
	log.AlertLevel,
	log.FatalLevel}

func getLogLevels(l log.Level) []log.Level {
	levels := make([]log.Level, 0)
	offset := int(l)
	levels = append(levels, logLevelsArray[offset:]...)
	return levels
}

func RegisterHandler(handler log.Handler, l log.Level) {
	log.RegisterHandler(handler, getLogLevels(l)...)
}

type BaseLogHandler struct {
}

func (l *BaseLogHandler) FormatMessage(e *log.Entry, w io.Writer) {
	now := e.Timestamp.In(time.Local)
	fmt.Fprintf(w, "[%s] %s - %s", e.Level,
		now.Format(l.getDefaultTimeLayout()), e.Message)
	for _, f := range e.Fields {
		fmt.Fprintf(w, " %s=%v", f.Key, f.Value)
	}
	w.Write([]byte("\n"))
}

func (l *BaseLogHandler) getDefaultTimeLayout() string {
	return "2006-01-02 15:04:05.000"
}

type FileLogHandler struct {
	*BaseLogHandler
	logFilePath string
	logHandler  *os.File
}

func checkAndCreateDir(path string) error {
	if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
		if err = os.MkdirAll(path, os.ModeDir|os.ModePerm); err != nil {
			return err
		}
	}
	return nil
}

func NewFileLogHandler(logPath string) *FileLogHandler {
	res := new(FileLogHandler)
	res.logFilePath = logPath
	return res
}

func (h *FileLogHandler) openLogFile() error {
	dir := filepath.Dir(h.logFilePath)
	var err error
	if err = checkAndCreateDir(dir); err != nil {
		return err
	}
	if h.logHandler, err = os.OpenFile(h.logFilePath,
		os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err != nil {
		return err
	}
	return nil
}

func (h *FileLogHandler) Run() chan<- *log.Entry {
	if err := h.openLogFile(); err != nil {
		panic(fmt.Sprintf("Can't open log file, Err=%v\n", err))
	}
	ch := make(chan *log.Entry, 5)
	go func(entries <-chan *log.Entry) {
		var e *log.Entry
		b := new(bytes.Buffer)
		defer h.logHandler.Close()
		for e = range entries {

			b.Reset()
			h.FormatMessage(e, b)
			io.Copy(h.logHandler, b)
			h.logHandler.Sync()
			e.Consumed()
		}
	}(ch)
	return ch
}

type RotateFileLogHandler struct {
	*BaseLogHandler
	logFilePath     string
	maxLogSize      int64
	maxLogFileCount int
	logCurrentSize  int64
	logHandler      *os.File
}

// NewRotateFileLogHandler
// maxSize in MB
func NewRotateFileLogHandler(logPath string, maxSize int, maxCount int) *RotateFileLogHandler {
	res := new(RotateFileLogHandler)
	res.logFilePath = logPath
	if maxSize < 1 || maxSize > 2000 {
		maxSize = 50
	}
	res.maxLogFileCount = maxCount
	res.maxLogSize = int64(maxSize) * 1024 * 1024
	return res
}

func (h *RotateFileLogHandler) checkFile() error {
	var err error
	dir := filepath.Dir(h.logFilePath)
	if err = checkAndCreateDir(dir); err != nil {
		return err
	}
	if h.logHandler, err = os.OpenFile(h.logFilePath,
		os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666); err != nil {
		return err
	}
	h.logHandler.Seek(0, os.SEEK_SET)
	n, _ := h.logHandler.Seek(0, os.SEEK_END)
	h.logCurrentSize = n
	return nil
}

func (h *RotateFileLogHandler) rotate() error {
	var backupFilePath string
	minModTime := time.Now()
	backupExists := true
	for i := 0; i < h.maxLogFileCount; i++ {
		fullPath := fmt.Sprintf("%v.%d", h.logFilePath, i+1)
		if stat, err := os.Stat(fullPath); err != nil {
			if os.IsNotExist(err) {
				backupFilePath = fullPath
				backupExists = false
				break
			} else {
				return err
			}
		} else {
			if stat.ModTime().Before(minModTime) {
				minModTime = stat.ModTime()
				backupFilePath = fullPath
			}
		}
	}
	if backupExists && len(backupFilePath) > 0 {
		os.Remove(backupFilePath)
	}
	if len(backupFilePath) > 0 {
		var err error
		h.logHandler.Close()
		h.logHandler = nil
		err = os.Rename(h.logFilePath, backupFilePath)
		if err != nil {
			fmt.Printf("Rename file Error=%v\n", err)
		}
		//		if stat, err := os.Stat(backupFilePath); err == nil {
		//			fmt.Printf("Backup file size:<%v>%v\n", backupFilePath, stat.Size())
		//		}
		h.logHandler, err = os.OpenFile(h.logFilePath,
			os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0660)
		if err != nil {
			return err
		}
		h.logCurrentSize = 0
	}
	return nil
}

func (h *RotateFileLogHandler) Run() chan<- *log.Entry {
	if err := h.checkFile(); err != nil {
		panic(fmt.Sprintf("Can't create file, Err=%v", err))
	}
	ch := make(chan *log.Entry, 5)
	go func(entries <-chan *log.Entry) {
		var e *log.Entry
		b := new(bytes.Buffer)
		defer h.logHandler.Close()
		for e = range entries {

			b.Reset()
			h.FormatMessage(e, b)
			h.logCurrentSize += int64(b.Len())
			if h.logHandler != nil {
				io.Copy(h.logHandler, b)
				// h.logHandler.Sync()
				if h.logCurrentSize >= h.maxLogSize {
					//fmt.Printf("Current Size=%v, old=%v\n", h.logCurrentSize, h.maxLogSize)
					h.rotate()
				}
			}
			e.Consumed()
		}
	}(ch)
	return ch
}
