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