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

	lpb "source.monogon.dev/metropolis/pkg/logtree/proto"
)

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

// Messages 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() *lpb.LogEntry_Leveled {
	return &lpb.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 *lpb.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
}
