package gologger

import (
	"os"
	"path/filepath"
)

type FileAppender struct {
	filePath string
	lchan    chan LogEvent
	file     *os.File
	stopChan chan struct{}
}

// Close implements LoggerAppender.
func (f *FileAppender) Close() {
	//send stop signal
	f.stopChan <- struct{}{}
}

func (f *FileAppender) GetName() string {
	return "FileAppender:" + f.filePath
}

func (f *FileAppender) start() {
	f.lchan = make(chan LogEvent, 10)
	f.stopChan = make(chan struct{})
	if f.file == nil || int(f.file.Fd()) == -1 {
		dirName := filepath.Dir(f.filePath)
		_, err := os.Stat(dirName)
		if err != nil && os.IsNotExist(err) {
			os.MkdirAll(dirName, 0755)
		}
		f.file, _ = os.OpenFile(f.filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	}

	go func() {
		defer f.file.Close()
		for {
			select {
			case <-f.stopChan:
				return
			case logEvent := <-f.lchan:
				logMsg := format(logEvent)
				f.file.WriteString(logMsg)
			}

		}
	}()
}
func (f *FileAppender) Append(logEvent LogEvent) {

	f.lchan <- logEvent
}

func makeFileAppender(appenderConfig LogAppenderConfig) *LoggerAppender {
	var logfile interface{}
	var ok bool
	logfile, ok = appenderConfig.Options["file"]
	if !ok {
		logfile = "default.log"
	}
	var ret LoggerAppender = &FileAppender{
		filePath: logfile.(string),
	}

	ret.(*FileAppender).start()

	return &ret
}

func init() {
	RegistAppender("file", makeFileAppender)
}
