package broker

import (
	"encoding/json"
	"sync"
	"time"
)

var (
	eventPool = new(sync.Pool)
)

func applyEvent() *Event {
	if v := eventPool.Get(); v == nil {
		return &Event{
			Timestamp: time.Now().Unix(),
		}
	} else {
		e := v.(*Event)
		e.Timestamp = time.Now().Unix()
		e.Header = make(map[string]string)
		e.Body = nil
		return e
	}
}

func releaseEvent(e *Event) {
	eventPool.Put(e)
}

type Event struct {
	Namespace string            `json:"-"`
	Name      string            `json:"name"`
	Trigger   string            `json:"-"` //触发的用户，用于一些订阅者过滤数据
	Timestamp int64             `json:"ts"`
	Header    map[string]string `json:"meta"`
	Body      []byte            `json:"body,omitempty"`
}

func (e *Event) WithTrigger(target string) *Event {
	e.Trigger = target
	return e
}

func (e *Event) Set(k, v string) *Event {
	if e.Header == nil {
		e.Header = make(map[string]string)
	}
	e.Header[k] = v
	return e
}

func (e *Event) MultiSet(ss ...string) *Event {
	if len(ss)%2 != 0 {
		return e
	}
	if e.Header == nil {
		e.Header = make(map[string]string)
	}
	for i := 0; i < len(ss); i += 2 {
		e.Header[ss[i]] = ss[i+1]
	}
	return e
}

func (e *Event) Get(k string) string {
	if e.Header == nil {
		return ""
	}
	return e.Header[k]
}

func (e *Event) Encode() (buf []byte) {
	buf, _ = json.Marshal(e)
	return
}

func NewEvent(namespace string, name string) *Event {
	e := applyEvent()
	e.Namespace = namespace
	e.Name = name
	return e
}
