// 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 provides support for event based telemetry.
package event

import (
	"fmt"
	"time"
)

type eventType uint8

const (
	invalidType   = eventType(iota)
	LogType       // an event that should be recorded in a log
	StartSpanType // the start of a span of time
	EndSpanType   // the end of a span of time
	LabelType     // some values that should be noted for later events
	DetachType    // an event that causes a context to detach
	RecordType    // a value that should be tracked
)

// sTags is used to hold a small number of tags inside an event whichout
// requiring a separate allocation.
// As tags are often on the stack, this avoids 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.
// A log message with two values will use 3 tags (one for each value and
// one for the message itself).
type sTags [3]Tag

// Event holds the information about an event of note that ocurred.
type Event struct {
	At time.Time

	typ     eventType
	static  sTags // inline storage for the first few tags
	dynamic []Tag // dynamically sized storage for remaining tags
}

// eventTagMap implements TagMap for a the tags of an Event.
type eventTagMap struct {
	event Event
}

func (ev Event) IsLog() bool       { return ev.typ == LogType }
func (ev Event) IsEndSpan() bool   { return ev.typ == EndSpanType }
func (ev Event) IsStartSpan() bool { return ev.typ == StartSpanType }
func (ev Event) IsLabel() bool     { return ev.typ == LabelType }
func (ev Event) IsDetach() bool    { return ev.typ == DetachType }
func (ev Event) IsRecord() bool    { return ev.typ == RecordType }

func (ev Event) Format(f fmt.State, r rune) {
	tagMap := ev.Map()
	if !ev.At.IsZero() {
		fmt.Fprint(f, ev.At.Format("2006/01/02 15:04:05 "))
	}
	msg := Msg.Get(tagMap)
	err := Err.Get(tagMap)
	fmt.Fprint(f, msg)
	if err != nil {
		if f.Flag('+') {
			fmt.Fprintf(f, ": %+v", err)
		} else {
			fmt.Fprintf(f, ": %v", err)
		}
	}
	for it := ev.Tags(); it.Valid(); it.Advance() {
		tag := it.Tag()
		fmt.Fprintf(f, "\n\t%v", tag)
	}
}

func (ev Event) Tags() TagIterator {
	return ChainTagIterators(
		NewTagIterator(ev.static[:]...),
		NewTagIterator(ev.dynamic...))
}

func (ev Event) Map() TagMap {
	return &eventTagMap{event: ev}
}

func (m *eventTagMap) Find(key interface{}) Tag {
	for _, tag := range m.event.static {
		if tag.Key == key {
			return tag
		}
	}
	for _, tag := range m.event.dynamic {
		if tag.Key == key {
			return tag
		}
	}
	return Tag{}
}

func makeEvent(typ eventType, static sTags, tags []Tag) Event {
	return Event{
		typ:     typ,
		static:  static,
		dynamic: tags,
	}
}
