// 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"
	"sync"

	"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     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()
	}
}
