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

import (
	"strings"
	"testing"
	"time"

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

func TestPrint(t *testing.T) {
	var p logfmt.Printer
	buf := &strings.Builder{}
	// the exporter is not used, but we need it to build the events
	at, _ := time.Parse(logfmt.TimeFormat, "2020/03/05 14:27:48")
	for _, test := range []struct {
		name   string
		event  event.Event
		expect string
	}{{
		name:   "empty",
		event:  event.Event{},
		expect: ``,
	}, {
		name:   "span",
		event:  event.Event{TraceID: 34},
		expect: `trace=34`,
	}, {
		name:   "parent",
		event:  event.Event{Parent: 14},
		expect: `parent=14`,
	}, {
		name:   "namespace",
		event:  event.Event{Namespace: "golang.org/x/exp/event"},
		expect: `in="golang.org/x/exp/event"`,
	}, {
		name:   "at",
		event:  event.Event{At: at},
		expect: `time="2020/03/05 14:27:48"`,
	}, {
		name:   "message",
		event:  event.Event{Labels: []event.Label{event.String("msg", "a message")}},
		expect: `msg="a message"`,
	}, {
		name:   "end",
		event:  event.Event{Kind: event.EndKind},
		expect: `end`,
	}, {
		name: "string",
		event: event.Event{
			Labels: []event.Label{
				event.String("v1", "text"),
				event.String("v2", "text with quotes"),
				event.String("empty", ""),
			},
		},
		expect: `v1=text v2="text with quotes" empty=""`,
	}, {
		name: "int",
		event: event.Event{
			Labels: []event.Label{
				event.Int64("value", 67),
			},
		},
		expect: `value=67`,
	}, {
		name: "float",
		event: event.Event{
			Labels: []event.Label{
				event.Float64("value", 263.2),
			},
		},
		expect: `value=263.2`,
	}, {
		name: "bool",
		event: event.Event{
			Labels: []event.Label{
				event.Bool("v1", true),
				event.Bool("v2", false),
			},
		},
		expect: `v1=true v2=false`,
	}, {
		name: "value",
		event: event.Event{
			Labels: []event.Label{
				event.Value("v1", notString{"simple"}),
				event.Value("v2", notString{"needs quoting"}),
			},
		},
		expect: `v1=simple v2="needs quoting"`,
	}, {
		name: "empty label",
		event: event.Event{
			Labels: []event.Label{
				event.Value("before", nil),
				event.String("", "text"),
				event.Value("after", nil),
			},
		},
		expect: `before after`,
	}, {
		name: "quoted ident",
		event: event.Event{
			Labels: []event.Label{
				event.String("name with space", "text"),
			},
		},
		expect: `"name with space"=text`,
	}, {
		name:   "quoting quote",
		event:  event.Event{Labels: []event.Label{event.String("msg", `with"middle`)}},
		expect: `msg="with\"middle"`,
	}, {
		name:   "quoting newline",
		event:  event.Event{Labels: []event.Label{event.String("msg", "with\nmiddle")}},
		expect: `msg="with\nmiddle"`,
	}, {
		name:   "quoting slash",
		event:  event.Event{Labels: []event.Label{event.String("msg", `with\middle`)}},
		expect: `msg="with\\middle"`,
	}, {
		name: "quoting bytes",
		event: event.Event{
			Labels: []event.Label{
				event.Bytes("value", ([]byte)(`bytes "need" quote`)),
			},
		},
		expect: `value="bytes \"need\" quote"`,
	}} {
		t.Run(test.name, func(t *testing.T) {
			buf.Reset()
			p.Event(buf, &test.event)
			got := strings.TrimSpace(buf.String())
			if got != test.expect {
				t.Errorf("got: \n%q\nexpect:\n%q\n", got, test.expect)
			}
		})
	}
}

type notString struct {
	value string
}

func (v notString) String() string { return v.value }

func TestPrinterFlags(t *testing.T) {
	var reference logfmt.Printer
	buf := &strings.Builder{}
	// the exporter is not used, but we need it to build the events
	for _, test := range []struct {
		name    string
		printer logfmt.Printer
		event   event.Event
		before  string
		after   string
	}{{
		name:    "quote values",
		printer: logfmt.Printer{QuoteValues: true},
		event: event.Event{
			Labels: []event.Label{
				event.String("value", "text"),
			},
		},
		before: `value=text`,
		after:  `value="text"`,
	}, {
		name:    "suppress namespace",
		printer: logfmt.Printer{SuppressNamespace: true},
		event: event.Event{
			Namespace: "golang.org/x/exp/event",
			Labels:    []event.Label{event.String("msg", "some text")},
		},
		before: `in="golang.org/x/exp/event" msg="some text"`,
		after:  `msg="some text"`,
	}} {
		t.Run(test.name, func(t *testing.T) {
			buf.Reset()
			reference.Event(buf, &test.event)
			gotBefore := strings.TrimSpace(buf.String())
			buf.Reset()
			test.printer.Event(buf, &test.event)
			gotAfter := strings.TrimSpace(buf.String())
			if gotBefore != test.before {
				t.Errorf("got: \n%q\nexpect:\n%q\n", gotBefore, test.before)
			}
			if gotAfter != test.after {
				t.Errorf("got: \n%q\nexpect:\n%q\n", gotAfter, test.after)
			}
		})
	}
}
