package galog

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

type GALogger struct {
	logger    *Logger
	projectID string
	clientID  string
	logType   LogType
	entryPool sync.Pool
}

type LogType string

const (
	// LogTypeTrack 事实日志
	LogTypeTrack LogType = "track"
	// LogTypeAsset 资产日志
	LogTypeAsset LogType = "asset"
)

const (
	// enableAsync 启用异步写入模式
	enableAsync = true
	// defaultAsyncMsgLen 异步写入模式的队列长度，QPS较大时可调整此值
	defaultAsyncMsgLen int64 = 100
)

// NewGALogger
//
//	logDir: 日志根目录 logs | /home/tywork
//	projectID: projectID
//	clientID: clientID
//	logType: galog.LogTypeTrack | galog.LogTypeAsset
func NewGALogger(logDir, projectID, clientID string, logType LogType) (*GALogger, error) {
	l := newLogger()
	hostname, _ := os.Hostname()
	filepath := fmt.Sprintf("ga_log/ga_%s.log", hostname)
	if logType == LogTypeAsset {
		filepath = fmt.Sprintf("asset_log/%s_%s.log", logType, hostname)
	}
	configs := fmt.Sprintf(`{"filename":"%s/%s"}`, strings.TrimRight(logDir, "/"), filepath)
	err := l.setLogger(AdapterFile, configs)
	if err != nil {
		return nil, err
	}
	if enableAsync {
		l.Async()
	}
	gaLogger := &GALogger{
		logger:    l,
		projectID: projectID,
		clientID:  clientID,
		logType:   logType,
	}

	return gaLogger, nil
}

// GetEntry
func (gl *GALogger) GetEntry(event string) *Entry {
	e, ok := gl.entryPool.Get().(*Entry)
	if ok {
		e.logger = gl
		e.bean.ProjectID = gl.projectID
		e.bean.LogType = gl.logType
		e.bean.ClientID = gl.clientID
		e.bean.Event = event
		e.bean.EventTime = time.Now().UnixMilli()
		e.bean.Lib = defaultLib
		return e
	}
	return &Entry{
		logger: gl,
		bean: &EntryBean{
			ProjectID: gl.projectID,
			LogType:   gl.logType,
			ClientID:  gl.clientID,
			Event:     event,
			EventTime: time.Now().UnixMilli(),
			Lib:       defaultLib,
		},
	}
}

func (gl *GALogger) biz(v interface{}) {
	gl.logger.BizErr(v)
}

func (gl *GALogger) putEntry(entry *Entry) {
	entry.bean = &EntryBean{}
	gl.entryPool.Put(entry)
}
