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

package logtree

import (
	"fmt"
	"io"
	"runtime"
	"strings"
	"time"

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

type leveledPublisher struct {
	node  *node
	depth int
}

// LeveledFor returns a LeveledLogger publishing interface for a given DN. An error
// may be returned if the DN is malformed.
func (l *LogTree) LeveledFor(dn DN) (logging.Leveled, error) {
	node, err := l.nodeByDN(dn)
	if err != nil {
		return nil, err
	}
	return &leveledPublisher{
		node:  node,
		depth: 0,
	}, nil
}

func (l *LogTree) RawFor(dn DN) (io.Writer, error) {
	node, err := l.nodeByDN(dn)
	if err != nil {
		return nil, fmt.Errorf("could not retrieve raw logger: %w", err)
	}
	return node.rawLineBuffer, nil
}

// MustLeveledFor returns a LeveledLogger publishing interface for a given DN, or
// panics if the given DN is invalid.
func (l *LogTree) MustLeveledFor(dn DN) logging.Leveled {
	leveled, err := l.LeveledFor(dn)
	if err != nil {
		panic(fmt.Errorf("LeveledFor returned: %w", err))
	}
	return leveled
}

func (l *LogTree) MustRawFor(dn DN) io.Writer {
	raw, err := l.RawFor(dn)
	if err != nil {
		panic(fmt.Errorf("RawFor returned: %w", err))
	}
	return raw
}

// SetVerbosity sets the verbosity for a given DN (non-recursively, ie. for that DN
// only, not its children).
func (l *LogTree) SetVerbosity(dn DN, level logging.VerbosityLevel) error {
	node, err := l.nodeByDN(dn)
	if err != nil {
		return err
	}
	node.verbosity = level
	return nil
}

// logRaw is called by this node's LineBuffer any time a raw log line is completed.
// It will create a new entry, append it to the journal, and notify all pertinent
// subscribers.
func (n *node) logRaw(line *logbuffer.Line) {
	e := &entry{
		origin: n.dn,
		raw:    line,
	}
	n.tree.journal.append(e)
	n.tree.journal.notify(e)
}

// LogExternalLeveled injects a ExternalLeveledPayload into a given
// LeveledLogger. This should only be used by systems which translate external
// data sources into leveled logging - see ExternelLeveledPayload for more
// information.
func LogExternalLeveled(l logging.Leveled, e *ExternalLeveledPayload) error {
	publisher, ok := l.(*leveledPublisher)
	if !ok {
		return fmt.Errorf("the given LeveledLogger is not a *leveledPublisher")
	}
	p := e.sanitize()
	entry := &entry{
		origin:  publisher.node.dn,
		leveled: p,
	}
	publisher.node.tree.journal.append(entry)
	publisher.node.tree.journal.notify(entry)
	return nil
}

// log builds a LeveledPayload and entry for a given message, including all related
// metadata. It will create a new entry append it to the journal, and notify all
// pertinent subscribers.
func (l *leveledPublisher) logLeveled(depth int, severity logging.Severity, msg string) {
	_, file, line, ok := runtime.Caller(2 + depth)
	if !ok {
		file = "???"
		line = 1
	} else {
		slash := strings.LastIndex(file, "/")
		if slash >= 0 {
			file = file[slash+1:]
		}
	}

	// Remove leading/trailing newlines and split.
	messages := strings.Split(strings.Trim(msg, "\n"), "\n")

	p := &LeveledPayload{
		timestamp: time.Now(),
		severity:  severity,
		messages:  messages,
		file:      file,
		line:      line,
	}
	e := &entry{
		origin:  l.node.dn,
		leveled: p,
	}
	l.node.tree.journal.append(e)
	l.node.tree.journal.notify(e)
}

// Info implements the LeveledLogger interface.
func (l *leveledPublisher) Info(args ...interface{}) {
	l.logLeveled(l.depth, logging.INFO, fmt.Sprint(args...))
}

// Infof implements the LeveledLogger interface.
func (l *leveledPublisher) Infof(format string, args ...interface{}) {
	l.logLeveled(l.depth, logging.INFO, fmt.Sprintf(format, args...))
}

// Warning implements the LeveledLogger interface.
func (l *leveledPublisher) Warning(args ...interface{}) {
	l.logLeveled(l.depth, logging.WARNING, fmt.Sprint(args...))
}

// Warningf implements the LeveledLogger interface.
func (l *leveledPublisher) Warningf(format string, args ...interface{}) {
	l.logLeveled(l.depth, logging.WARNING, fmt.Sprintf(format, args...))
}

// Error implements the LeveledLogger interface.
func (l *leveledPublisher) Error(args ...interface{}) {
	l.logLeveled(l.depth, logging.ERROR, fmt.Sprint(args...))
}

// Errorf implements the LeveledLogger interface.
func (l *leveledPublisher) Errorf(format string, args ...interface{}) {
	l.logLeveled(l.depth, logging.ERROR, fmt.Sprintf(format, args...))
}

// Fatal implements the LeveledLogger interface.
func (l *leveledPublisher) Fatal(args ...interface{}) {
	l.logLeveled(l.depth, logging.FATAL, fmt.Sprint(args...))
}

// Fatalf implements the LeveledLogger interface.
func (l *leveledPublisher) Fatalf(format string, args ...interface{}) {
	l.logLeveled(l.depth, logging.FATAL, fmt.Sprintf(format, args...))
}

// WithAddedStackDepth impleemnts the LeveledLogger interface.
func (l *leveledPublisher) WithAddedStackDepth(depth int) logging.Leveled {
	l2 := *l
	l2.depth += depth
	return &l2
}

// V implements the LeveledLogger interface.
func (l *leveledPublisher) V(v logging.VerbosityLevel) logging.VerboseLeveled {
	return &verbose{
		publisher: l,
		enabled:   l.node.verbosity >= v,
	}
}

// verbose implements the VerboseLeveledLogger interface. It is a thin wrapper
// around node, with an 'enabled' bool. This means that V(n)-returned
// VerboseLeveledLoggers must be short lived, as a changed in verbosity will not
// affect all already existing VerboseLeveledLoggers.
type verbose struct {
	publisher *leveledPublisher
	node      *node
	enabled   bool
}

func (v *verbose) Enabled() bool {
	return v.enabled
}

func (v *verbose) Info(args ...interface{}) {
	if !v.enabled {
		return
	}
	v.publisher.logLeveled(v.publisher.depth, logging.INFO, fmt.Sprint(args...))
}

func (v *verbose) Infof(format string, args ...interface{}) {
	if !v.enabled {
		return
	}
	v.publisher.logLeveled(v.publisher.depth, logging.INFO, fmt.Sprintf(format, args...))
}
