// 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 logfmt

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"strconv"
	"time"
	"unicode/utf8"

	"golang.org/x/exp/event"
)

//TODO: some actual research into what this arbritray optimization number should be
const bufCap = 50

const TimeFormat = "2006/01/02 15:04:05"

type Printer struct {
	QuoteValues       bool
	SuppressNamespace bool
	buf               [bufCap]byte
	needSep           bool
	w                 bytes.Buffer
}

type Handler struct {
	to io.Writer
	Printer
}

// NewHandler returns a handler that prints the events to the supplied writer.
// Each event is printed in logfmt format on a single line.
func NewHandler(to io.Writer) *Handler {
	return &Handler{to: to}
}

func (h *Handler) Event(ctx context.Context, ev *event.Event) context.Context {
	h.Printer.Event(h.to, ev)
	return ctx
}

func (p *Printer) Event(w io.Writer, ev *event.Event) {
	p.needSep = false
	if !ev.At.IsZero() {
		p.separator(w)
		io.WriteString(w, `time="`)
		p.time(w, ev.At)
		io.WriteString(w, `"`)
	}

	if !p.SuppressNamespace && ev.Source.Space != "" {
		p.Label(w, event.String("in", ev.Source.Space))
	}
	if ev.Source.Owner != "" {
		p.Label(w, event.String("owner", ev.Source.Owner))
	}
	if ev.Source.Name != "" {
		p.Label(w, event.String("name", ev.Source.Name))
	}

	if ev.Parent != 0 {
		p.separator(w)
		io.WriteString(w, `parent=`)
		w.Write(strconv.AppendUint(p.buf[:0], ev.Parent, 10))
	}
	for _, l := range ev.Labels {
		if l.Name == "" {
			continue
		}
		p.Label(w, l)
	}

	if ev.ID != 0 {
		p.separator(w)
		io.WriteString(w, `trace=`)
		w.Write(strconv.AppendUint(p.buf[:0], ev.ID, 10))
	}

	if ev.Kind == event.EndKind {
		p.separator(w)
		io.WriteString(w, `end`)
	}

	io.WriteString(w, "\n")
}

func (p *Printer) separator(w io.Writer) {
	if p.needSep {
		io.WriteString(w, " ")
	}
	p.needSep = true
}

func (p *Printer) Label(w io.Writer, l event.Label) {
	if l.Name == "" {
		return
	}
	p.separator(w)
	p.Ident(w, l.Name)
	if l.HasValue() {
		io.WriteString(w, "=")
		switch {
		case l.IsString():
			p.string(w, l.String())
		case l.IsBytes():
			p.bytes(w, l.Bytes())
		case l.IsInt64():
			w.Write(strconv.AppendInt(p.buf[:0], l.Int64(), 10))
		case l.IsUint64():
			w.Write(strconv.AppendUint(p.buf[:0], l.Uint64(), 10))
		case l.IsFloat64():
			w.Write(strconv.AppendFloat(p.buf[:0], l.Float64(), 'g', -1, 64))
		case l.IsBool():
			if l.Bool() {
				io.WriteString(w, "true")
			} else {
				io.WriteString(w, "false")
			}
		default:
			v := l.Interface()
			switch v := v.(type) {
			case string:
				p.string(w, v)
			case fmt.Stringer:
				p.string(w, v.String())
			default:
				if p.w.Cap() == 0 {
					// we rely on the inliner to cause this to not allocate
					p.w = *bytes.NewBuffer(p.buf[:0])
				}
				fmt.Fprint(&p.w, v)
				b := p.w.Bytes()
				p.w.Reset()
				p.bytes(w, b)
			}
		}
	}
}

func (p *Printer) Ident(w io.Writer, s string) {
	if !stringNeedQuote(s) {
		io.WriteString(w, s)
		return
	}
	p.quoteString(w, s)
}

func (p *Printer) string(w io.Writer, s string) {
	if p.QuoteValues || stringNeedQuote(s) {
		p.quoteString(w, s)
	} else {
		io.WriteString(w, s)
	}
}

func (p *Printer) quoteString(w io.Writer, s string) {
	io.WriteString(w, `"`)
	written := 0
	for offset, r := range s {
		q := quoteRune(r)
		if len(q) == 0 {
			continue
		}
		// write out any prefix
		io.WriteString(w, s[written:offset])
		written = offset + utf8.RuneLen(r)
		// and write out the quoted rune
		io.WriteString(w, q)
	}
	io.WriteString(w, s[written:])
	io.WriteString(w, `"`)
}

func (p *Printer) bytes(w io.Writer, buf []byte) {
	if p.QuoteValues || stringNeedQuote(string(buf)) {
		p.quoteBytes(w, buf)
	} else {
		w.Write(buf)
	}
}

// Bytes writes a byte array in string form to the printer.
func (p *Printer) quoteBytes(w io.Writer, buf []byte) {
	io.WriteString(w, `"`)
	written := 0
	for offset := 0; offset < len(buf); {
		r, size := utf8.DecodeRune(buf[offset:])
		offset += size
		q := quoteRune(r)
		if len(q) == 0 {
			continue
		}
		// write out any prefix
		w.Write(buf[written : offset-size])
		written = offset
		// and write out the quoted rune
		io.WriteString(w, q)
	}
	w.Write(buf[written:])
	io.WriteString(w, `"`)
}

// time writes a timstamp in the same format as
func (p *Printer) time(w io.Writer, t time.Time) {
	year, month, day := t.Date()
	hour, minute, second := t.Clock()
	p.padInt(w, int64(year), 4)
	io.WriteString(w, `/`)
	p.padInt(w, int64(month), 2)
	io.WriteString(w, `/`)
	p.padInt(w, int64(day), 2)
	io.WriteString(w, ` `)
	p.padInt(w, int64(hour), 2)
	io.WriteString(w, `:`)
	p.padInt(w, int64(minute), 2)
	io.WriteString(w, `:`)
	p.padInt(w, int64(second), 2)
}

func (p *Printer) padInt(w io.Writer, v int64, width int) {
	b := strconv.AppendInt(p.buf[:0], int64(v), 10)
	if len(b) < width {
		io.WriteString(w, "0000"[:width-len(b)])
	}
	w.Write(b)
}

func stringNeedQuote(s string) bool {
	if len(s) == 0 {
		return true
	}
	for i := 0; i < len(s); i++ {
		c := s[i]
		if c >= utf8.RuneSelf || c == ' ' || c == '"' || c == '\n' || c == '\\' {
			return true
		}
	}
	return false
}

func quoteRune(r rune) string {
	switch r {
	case '"':
		return `\"`
	case '\n':
		return `\n`
	case '\\':
		return `\\`
	default:
		return ``
	}
}
