// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package event

import (
	"context"
	"sync"
	"time"
)

// Event holds the information about an event that occurred.
// It combines the event metadata with the user supplied labels.
type Event struct {
	ID     uint64
	Parent uint64    // id of the parent event for this event
	Source Source    // source of event; if empty, set by exporter to import path
	At     time.Time // time at which the event is delivered to the exporter.
	Kind   Kind
	Labels []Label

	ctx    context.Context
	target *target
	labels [preallocateLabels]Label
}

// Handler is a the type for something that handles events as they occur.
type Handler interface {
	// Event is called with each event.
	Event(context.Context, *Event) context.Context
}

// preallocateLabels controls the space reserved for labels in a builder.
// Storing the first few labels directly in builders can avoid an allocation at
// all for the very common cases of simple events. The length needs to be large
// enough to cope with the majority of events but no so large as to cause undue
// stack pressure.
const preallocateLabels = 6

var eventPool = sync.Pool{New: func() interface{} { return &Event{} }}

// WithExporter returns a context with the exporter attached.
// The exporter is called synchronously from the event call site, so it should
// return quickly so as not to hold up user code.
func WithExporter(ctx context.Context, e *Exporter) context.Context {
	return newContext(ctx, e, 0, time.Time{})
}

// SetDefaultExporter sets an exporter that is used if no exporter can be
// found on the context.
func SetDefaultExporter(e *Exporter) {
	setDefaultExporter(e)
}

// New prepares a new event.
// This is intended to avoid allocations in the steady state case, to do this
// it uses a pool of events.
// Events are returned to the pool when Deliver is called. Failure to call
// Deliver will exhaust the pool and cause allocations.
// It returns nil if there is no active exporter for this kind of event.
func New(ctx context.Context, kind Kind) *Event {
	var t *target
	if v, ok := ctx.Value(contextKey).(*target); ok {
		t = v
	} else {
		t = getDefaultTarget()
	}
	if t == nil {
		return nil
	}
	//TODO: we can change this to a much faster test
	switch kind {
	case LogKind:
		if !t.exporter.loggingEnabled() {
			return nil
		}
	case MetricKind:
		if !t.exporter.metricsEnabled() {
			return nil
		}
	case StartKind, EndKind:
		if !t.exporter.tracingEnabled() {
			return nil
		}
	}
	ev := eventPool.Get().(*Event)
	*ev = Event{
		ctx:    ctx,
		target: t,
		Kind:   kind,
		Parent: t.parent,
	}
	ev.Labels = ev.labels[:0]
	return ev
}

// Clone makes a deep copy of the Event.
// Deliver can be called on both Events independently.
func (ev *Event) Clone() *Event {
	ev2 := eventPool.Get().(*Event)
	*ev2 = *ev
	ev2.Labels = append(ev2.labels[:0], ev.Labels...)
	return ev2
}

// Deliver the event to the exporter that was found in New.
// This also returns the event to the pool, it is an error to do anything
// with the event after it is delivered.
func (ev *Event) Deliver() context.Context {
	e := ev.target.exporter
	// get the event ready to send
	e.prepare(ev)
	// now hold the lock while we deliver the event
	e.mu.Lock()
	defer e.mu.Unlock()
	ctx := e.handler.Event(ev.ctx, ev)
	eventPool.Put(ev)
	return ctx
}
