// 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"
	"strconv"
	"strings"
	"time"

	tpb "google.golang.org/protobuf/types/known/timestamppb"

	cpb "source.monogon.dev/metropolis/proto/common"
)

// LeveledPayload is a log entry for leveled logs (as per leveled.go). It contains
// the input to these calls (severity and message split into newline-delimited
// messages) and additional metadata that would be usually seen in a text
// representation of a leveled log entry.
type LeveledPayload struct {
	// messages is the list of messages contained in this payload. This list is built
	// from splitting up the given message from the user by newline.
	messages []string
	// timestamp is the time at which this message was emitted.
	timestamp time.Time
	// severity is the leveled Severity at which this message was emitted.
	severity Severity
	// file is the filename of the caller that emitted this message.
	file string
	// line is the line number within the file of the caller that emitted this message.
	line int
}

// String returns a canonical representation of this payload as a single string
// prefixed with metadata. If the original message was logged with newlines, this
// representation will also contain newlines, with each original message part
// prefixed by the metadata. For an alternative call that will instead return a
// canonical prefix and a list of lines in the message, see Strings().
func (p *LeveledPayload) String() string {
	prefix, lines := p.Strings()
	res := make([]string, len(p.messages))
	for i, line := range lines {
		res[i] = fmt.Sprintf("%s%s", prefix, line)
	}
	return strings.Join(res, "\n")
}

// Strings returns the canonical representation of this payload split into a
// prefix and all lines that were contained in the original message. This is
// meant to be displayed to the user by showing the prefix before each line,
// concatenated together - possibly in a table form with the prefixes all
// unified with a rowspan- like mechanism.
//
// For example, this function can return:
//
//	prefix = "I1102 17:20:06.921395 foo.go:42] "
//	lines = []string{"current tags:", " - one", " - two"}
//
// With this data, the result should be presented to users this way in text form:
// I1102 17:20:06.921395 foo.go:42] current tags:
// I1102 17:20:06.921395 foo.go:42]  - one
// I1102 17:20:06.921395 foo.go:42]  - two
//
// Or, in a table layout:
// .-----------------------------------------------------------.
// | I1102 17:20:06.921395     0 foo.go:42] : current tags:    |
// |                                        :------------------|
// |                                        :  - one           |
// |                                        :------------------|
// |                                        :  - two           |
// '-----------------------------------------------------------'
func (p *LeveledPayload) Strings() (prefix string, lines []string) {
	_, month, day := p.timestamp.Date()
	hour, minute, second := p.timestamp.Clock()
	nsec := p.timestamp.Nanosecond() / 1000

	// Same format as in glog, but without treadid.
	// Lmmdd hh:mm:ss.uuuuuu file:line]
	// TODO(q3k): rewrite this to printf-less code.
	prefix = fmt.Sprintf("%s%02d%02d %02d:%02d:%02d.%06d %s:%d] ", p.severity, month, day, hour, minute, second, nsec, p.file, p.line)

	lines = p.messages
	return
}

// Message returns the inner message lines of this entry, ie. what was passed to
// the actual logging method, but split by newlines.
func (p *LeveledPayload) Messages() []string { return p.messages }

func (p *LeveledPayload) MessagesJoined() string { return strings.Join(p.messages, "\n") }

// Timestamp returns the time at which this entry was logged.
func (p *LeveledPayload) Timestamp() time.Time { return p.timestamp }

// Location returns a string in the form of file_name:line_number that shows the
// origin of the log entry in the program source.
func (p *LeveledPayload) Location() string { return fmt.Sprintf("%s:%d", p.file, p.line) }

// Severity returns the Severity with which this entry was logged.
func (p *LeveledPayload) Severity() Severity { return p.severity }

// Proto converts a LeveledPayload to protobuf format.
func (p *LeveledPayload) Proto() *cpb.LogEntry_Leveled {
	return &cpb.LogEntry_Leveled{
		Lines:     p.Messages(),
		Timestamp: tpb.New(p.Timestamp()),
		Severity:  p.Severity().ToProto(),
		Location:  p.Location(),
	}
}

// LeveledPayloadFromProto parses a protobuf message into the internal format.
func LeveledPayloadFromProto(p *cpb.LogEntry_Leveled) (*LeveledPayload, error) {
	severity, err := SeverityFromProto(p.Severity)
	if err != nil {
		return nil, fmt.Errorf("could not convert severity: %w", err)
	}
	parts := strings.Split(p.Location, ":")
	if len(parts) != 2 {
		return nil, fmt.Errorf("invalid location, must be two :-delimited parts, is %d parts", len(parts))
	}
	file := parts[0]
	line, err := strconv.Atoi(parts[1])
	if err != nil {
		return nil, fmt.Errorf("invalid location line number: %w", err)
	}
	return &LeveledPayload{
		messages:  p.Lines,
		timestamp: p.Timestamp.AsTime(),
		severity:  severity,
		file:      file,
		line:      line,
	}, nil
}

// ExternalLeveledPayload is a LeveledPayload received from an external source,
// eg. from parsing the logging output of third-party programs. It can be
// converted into a LeveledPayload and inserted into a leveled logger, but will
// be sanitized before that, ensuring that potentially buggy
// emitters/converters do not end up polluting the leveled logger data.
//
// This type should be used only when inserting data from external systems, not
// by code that just wishes to log things. In the future, data inserted this
// way might be explicitly marked as tainted so operators can understand that
// parts of this data might not give the same guarantees as the log entries
// emitted by the native LeveledLogger API.
type ExternalLeveledPayload struct {
	// Log line. If any newlines are found, they will split the message into
	// multiple messages within LeveledPayload. Empty messages are accepted
	// verbatim.
	Message string
	// Timestamp when this payload was emitted according to its source. If not
	// given, will default to the time of conversion to LeveledPayload.
	Timestamp time.Time
	// Log severity. If invalid or unset will default to INFO.
	Severity Severity
	// File name of originating code. Defaults to "unknown" if not set.
	File string
	// Line in File. Zero indicates the line is not known.
	Line int
}

// sanitize the given ExternalLeveledPayload by creating a corresponding
// LeveledPayload. The original object is unaltered.
func (e *ExternalLeveledPayload) sanitize() *LeveledPayload {
	l := &LeveledPayload{
		messages:  strings.Split(e.Message, "\n"),
		timestamp: e.Timestamp,
		severity:  e.Severity,
		file:      e.File,
		line:      e.Line,
	}
	if l.timestamp.IsZero() {
		l.timestamp = time.Now()
	}
	if !l.severity.Valid() {
		l.severity = INFO
	}
	if l.file == "" {
		l.file = "unknown"
	}
	if l.line < 0 {
		l.line = 0
	}
	return l
}
