// Copyright The Monogon Project Authors.
// SPDX-License-Identifier: Apache-2.0

package logtree

import (
	"fmt"
	"strings"
	"sync"

	"source.monogon.dev/go/logging"
	"source.monogon.dev/osbase/logbuffer"
)

// LogTree is a tree-shaped logging system. For more information, see the package-
// level documentation.
type LogTree struct {
	// journal is the tree's journal, storing all log data and managing subscribers.
	journal *journal
	// root is the root node of the actual tree of the log tree. The nodes contain per-
	// DN configuration options, notably the current verbosity level of that DN.
	root *node
}

func New() *LogTree {
	lt := &LogTree{
		journal: newJournal(),
	}
	lt.root = newNode(lt, "")
	return lt
}

// node represents a given DN as a discrete 'logger'. It implements the
// LeveledLogger interface for log publishing, entries from which it passes over to
// the logtree's journal.
type node struct {
	// dn is the DN which this node represents (or "" if this is the root node).
	dn DN
	// tree is the LogTree to which this node belongs.
	tree *LogTree
	// verbosity is the current verbosity level of this DN/node, affecting .V(n)
	// LeveledLogger calls
	verbosity     logging.VerbosityLevel
	rawLineBuffer *logbuffer.LineBuffer

	// mu guards children.
	mu sync.Mutex
	// children is a map of DN-part to a children node in the logtree. A DN-part is a
	// string representing a part of the DN between the deliming dots, as returned by
	// DN.Path.
	children map[string]*node
}

// newNode returns a node at a given DN in the LogTree - but doesn't set up the
// LogTree to insert it accordingly.
func newNode(tree *LogTree, dn DN) *node {
	n := &node{
		dn:       dn,
		tree:     tree,
		children: make(map[string]*node),
	}
	// TODO(q3k): make this limit configurable. If this happens, or the default (1024) gets changes, max chunk size
	// calculations when serving the logs (eg. in NodeDebugService) must reflect this.
	n.rawLineBuffer = logbuffer.NewLineBuffer(1024, n.logRaw)
	return n
}

// nodeByDN returns the LogTree node corresponding to a given DN. If either the
// node or some of its parents do not exist they will be created as needed.
func (l *LogTree) nodeByDN(dn DN) (*node, error) {
	traversal, err := newTraversal(dn)
	if err != nil {
		return nil, fmt.Errorf("traversal failed: %w", err)
	}
	return traversal.execute(l.root), nil
}

// nodeTraversal represents a request to traverse the LogTree in search of a given
// node by DN.
type nodeTraversal struct {
	// want is the DN of the node's that requested to be found.
	want DN
	// current is the path already taken to find the node, in the form of DN parts. It
	// starts out as want.Parts() and progresses to become empty as the traversal
	// continues.
	current []string
	// left is the path that's still needed to be taken in order to find the node, in
	// the form of DN parts. It starts out empty and progresses to become wants.Parts()
	// as the traversal continues.
	left []string
}

// next adjusts the traversal's current/left slices to the next element of the
// traversal, returns the part that's now being looked for (or "" if the traveral
// is done) and the full DN of the element that's being looked for.
//
// For example, a traversal of foo.bar.baz will cause .next() to return the
// following on each invocation:
//   - part: foo, full: foo
//   - part: bar, full: foo.bar
//   - part: baz, full: foo.bar.baz
//   - part: "",  full: foo.bar.baz
func (t *nodeTraversal) next() (part string, full DN) {
	if len(t.left) == 0 {
		return "", t.want
	}
	part = t.left[0]
	t.current = append(t.current, part)
	t.left = t.left[1:]
	full = DN(strings.Join(t.current, "."))
	return
}

// newTraversal returns a nodeTraversal fora a given wanted DN.
func newTraversal(dn DN) (*nodeTraversal, error) {
	parts, err := dn.Path()
	if err != nil {
		return nil, err
	}
	return &nodeTraversal{
		want: dn,
		left: parts,
	}, nil
}

// execute the traversal in order to find the node. This can only be called once
// per traversal. Nodes will be created within the tree until the target node is
// reached. Existing nodes will be reused. This is effectively an idempotent way of
// accessing a node in the tree based on a traversal.
func (t *nodeTraversal) execute(n *node) *node {
	cur := n
	for {
		part, full := t.next()
		if part == "" {
			return cur
		}

		mu := &cur.mu
		mu.Lock()
		if _, ok := cur.children[part]; !ok {
			cur.children[part] = newNode(n.tree, full)
		}
		cur = cur.children[part]
		mu.Unlock()
	}
}
