// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package logtree

import (
	"fmt"
	"strings"
	"testing"
	"time"
)

func expect(tree *LogTree, t *testing.T, dn DN, entries ...string) string {
	t.Helper()
	res, err := tree.Read(dn, WithChildren(), WithBacklog(BacklogAllAvailable))
	if err != nil {
		t.Fatalf("Read: %v", err)
	}
	if want, got := len(entries), len(res.Backlog); want != got {
		t.Fatalf("wanted %v backlog entries, got %v", want, got)
	}
	got := make(map[string]bool)
	for _, entry := range res.Backlog {
		if entry.Leveled != nil {
			got[entry.Leveled.MessagesJoined()] = true
		}
		if entry.Raw != nil {
			got[entry.Raw.Data] = true
		}
	}
	for _, entry := range entries {
		if !got[entry] {
			return fmt.Sprintf("missing entry %q", entry)
		}
	}
	return ""
}

func TestMultiline(t *testing.T) {
	tree := New()
	// Two lines in a single message.
	tree.MustLeveledFor("main").Info("foo\nbar")
	// Two lines in a single message with a hanging newline that should get stripped.
	tree.MustLeveledFor("main").Info("one\ntwo\n")

	if res := expect(tree, t, "main", "foo\nbar", "one\ntwo"); res != "" {
		t.Errorf("retrieval at main failed: %s", res)
	}
}

func TestBacklog(t *testing.T) {
	tree := New()
	tree.MustLeveledFor("main").Info("hello, main!")
	tree.MustLeveledFor("main.foo").Info("hello, main.foo!")
	tree.MustLeveledFor("main.bar").Info("hello, main.bar!")
	tree.MustLeveledFor("aux").Info("hello, aux!")
	// No newline at the last entry - shouldn't get propagated to the backlog.
	fmt.Fprintf(tree.MustRawFor("aux.process"), "processing foo\nprocessing bar\nbaz")

	if res := expect(tree, t, "main", "hello, main!", "hello, main.foo!", "hello, main.bar!"); res != "" {
		t.Errorf("retrieval at main failed: %s", res)
	}
	if res := expect(tree, t, "", "hello, main!", "hello, main.foo!", "hello, main.bar!", "hello, aux!", "processing foo", "processing bar"); res != "" {
		t.Errorf("retrieval at root failed: %s", res)
	}
	if res := expect(tree, t, "aux", "hello, aux!", "processing foo", "processing bar"); res != "" {
		t.Errorf("retrieval at aux failed: %s", res)
	}
}

func TestStream(t *testing.T) {
	tree := New()
	tree.MustLeveledFor("main").Info("hello, backlog")
	fmt.Fprintf(tree.MustRawFor("main.process"), "hello, raw backlog\n")

	res, err := tree.Read("", WithBacklog(BacklogAllAvailable), WithChildren(), WithStream())
	if err != nil {
		t.Fatalf("Read: %v", err)
	}
	defer res.Close()
	if want, got := 2, len(res.Backlog); want != got {
		t.Errorf("wanted %d backlog item, got %d", want, got)
	}

	tree.MustLeveledFor("main").Info("hello, stream")
	fmt.Fprintf(tree.MustRawFor("main.raw"), "hello, raw stream\n")

	entries := make(map[string]bool)
	timeout := time.After(time.Second * 1)
	for {
		done := false
		select {
		case <-timeout:
			done = true
		case p := <-res.Stream:
			if p.Leveled != nil {
				entries[p.Leveled.MessagesJoined()] = true
			}
			if p.Raw != nil {
				entries[p.Raw.Data] = true
			}
		}
		if done {
			break
		}
	}
	if entry := "hello, stream"; !entries[entry] {
		t.Errorf("Missing entry %q", entry)
	}
	if entry := "hello, raw stream"; !entries[entry] {
		t.Errorf("Missing entry %q", entry)
	}
}

func TestVerbose(t *testing.T) {
	tree := New()

	tree.MustLeveledFor("main").V(10).Info("this shouldn't get logged")

	reader, err := tree.Read("", WithBacklog(BacklogAllAvailable), WithChildren())
	if err != nil {
		t.Fatalf("Read: %v", err)
	}
	if want, got := 0, len(reader.Backlog); want != got {
		t.Fatalf("expected nothing to be logged, got %+v", reader.Backlog)
	}

	tree.SetVerbosity("main", 10)
	tree.MustLeveledFor("main").V(10).Info("this should get logged")

	reader, err = tree.Read("", WithBacklog(BacklogAllAvailable), WithChildren())
	if err != nil {
		t.Fatalf("Read: %v", err)
	}
	if want, got := 1, len(reader.Backlog); want != got {
		t.Fatalf("expected %d entries to get logged, got %d", want, got)
	}
}

func TestMetadata(t *testing.T) {
	tree := New()
	tree.MustLeveledFor("main").Error("i am an error")
	tree.MustLeveledFor("main").Warning("i am a warning")
	tree.MustLeveledFor("main").Info("i am informative")
	tree.MustLeveledFor("main").V(0).Info("i am a zero-level debug")

	reader, err := tree.Read("", WithChildren(), WithBacklog(BacklogAllAvailable))
	if err != nil {
		t.Fatalf("Read: %v", err)
	}
	if want, got := 4, len(reader.Backlog); want != got {
		t.Fatalf("expected %d entries, got %d", want, got)
	}

	for _, te := range []struct {
		ix       int
		severity Severity
		message  string
	}{
		{0, ERROR, "i am an error"},
		{1, WARNING, "i am a warning"},
		{2, INFO, "i am informative"},
		{3, INFO, "i am a zero-level debug"},
	} {
		p := reader.Backlog[te.ix]
		if want, got := te.severity, p.Leveled.Severity(); want != got {
			t.Errorf("wanted element %d to have severity %s, got %s", te.ix, want, got)
		}
		if want, got := te.message, p.Leveled.MessagesJoined(); want != got {
			t.Errorf("wanted element %d to have message %q, got %q", te.ix, want, got)
		}
		if want, got := "logtree_test.go", strings.Split(p.Leveled.Location(), ":")[0]; want != got {
			t.Errorf("wanted element %d to have file %q, got %q", te.ix, want, got)
		}
	}
}

func TestSeverity(t *testing.T) {
	tree := New()
	tree.MustLeveledFor("main").Error("i am an error")
	tree.MustLeveledFor("main").Warning("i am a warning")
	tree.MustLeveledFor("main").Info("i am informative")
	tree.MustLeveledFor("main").V(0).Info("i am a zero-level debug")

	reader, err := tree.Read("main", WithBacklog(BacklogAllAvailable), LeveledWithMinimumSeverity(WARNING))
	if err != nil {
		t.Fatalf("Read: %v", err)
	}
	if want, got := 2, len(reader.Backlog); want != got {
		t.Fatalf("wanted %d entries, got %d", want, got)
	}
	if want, got := "i am an error", reader.Backlog[0].Leveled.MessagesJoined(); want != got {
		t.Fatalf("wanted entry %q, got %q", want, got)
	}
	if want, got := "i am a warning", reader.Backlog[1].Leveled.MessagesJoined(); want != got {
		t.Fatalf("wanted entry %q, got %q", want, got)
	}
}
