package syslog

import (
    "go.uber.org/atomic"
    "sync"
)

var uswManager=map[string]*UniqueSyslogWriter{}
var uswManagerLock = &sync.Mutex{}
type UniqueSyslogWriter struct {
    *SysLogHandle
    // 引用计数
    count *atomic.Int32
}

func (usw *UniqueSyslogWriter)Close()(err error){
    r := usw.count.Dec()
    // 引用删除，调用 客户端 的 close 方法
    if r <= 0{
        return usw.SysLogHandle.Close()
    }
    return
}

func (usw *UniqueSyslogWriter)Reference(){
    usw.count.Inc()
}
func (usw *UniqueSyslogWriter)DeReference(){
    usw.count.Dec()
}
func (usw *UniqueSyslogWriter)Referenced()int32{
    return usw.count.Load()
}
func (usw *UniqueSyslogWriter)Sync()error{

    return usw.SysLogHandle.Flush()
}
// ClearSyslogWriter 清理不用的 syslog
func ClearSyslogWriter(){
    uswManagerLock.Lock()
    defer uswManagerLock.Unlock()
    for _, w := range uswManager{
        w.Close()
    }
}

// NewTcpSyslog 创建 syslog writer
func NewTcpSyslog(raddr string,opts ...OptionFunc) ( *UniqueSyslogWriter, error){

    uswManagerLock.Lock()
    defer uswManagerLock.Unlock()

    w,ok :=uswManager[raddr]
    // client 已经存在
    if  ok{
        w.Reference()
        return w,nil
    }

    sysLog,err :=  DialByLevel("tcp",raddr,"INFO",opts...)
    if err != nil{
        sysLog.Close()
        return nil,err
    }

    w = &UniqueSyslogWriter{sysLog,atomic.NewInt32(1)}
    uswManager[raddr] = w
    return w,err
}