//go:build go1.21
// +build go1.21

/*
Copyright 2023 The logr Authors.

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 logr

import (
	"context"
	"log/slog"
	"runtime"
	"time"
)

var (
	_ LogSink          = &slogSink{}
	_ CallDepthLogSink = &slogSink{}
	_ Underlier        = &slogSink{}
)

// Underlier is implemented by the LogSink returned by NewFromLogHandler.
type Underlier interface {
	// GetUnderlying returns the Handler used by the LogSink.
	GetUnderlying() slog.Handler
}

const (
	// nameKey is used to log the `WithName` values as an additional attribute.
	nameKey = "logger"

	// errKey is used to log the error parameter of Error as an additional attribute.
	errKey = "err"
)

type slogSink struct {
	callDepth int
	name      string
	handler   slog.Handler
}

func (l *slogSink) Init(info RuntimeInfo) {
	l.callDepth = info.CallDepth
}

func (l *slogSink) GetUnderlying() slog.Handler {
	return l.handler
}

func (l *slogSink) WithCallDepth(depth int) LogSink {
	newLogger := *l
	newLogger.callDepth += depth
	return &newLogger
}

func (l *slogSink) Enabled(level int) bool {
	return l.handler.Enabled(context.Background(), slog.Level(-level))
}

func (l *slogSink) Info(level int, msg string, kvList ...interface{}) {
	l.log(nil, msg, slog.Level(-level), kvList...)
}

func (l *slogSink) Error(err error, msg string, kvList ...interface{}) {
	l.log(err, msg, slog.LevelError, kvList...)
}

func (l *slogSink) log(err error, msg string, level slog.Level, kvList ...interface{}) {
	var pcs [1]uintptr
	// skip runtime.Callers, this function, Info/Error, and all helper functions above that.
	runtime.Callers(3+l.callDepth, pcs[:])

	record := slog.NewRecord(time.Now(), level, msg, pcs[0])
	if l.name != "" {
		record.AddAttrs(slog.String(nameKey, l.name))
	}
	if err != nil {
		record.AddAttrs(slog.Any(errKey, err))
	}
	record.Add(kvList...)
	_ = l.handler.Handle(context.Background(), record)
}

func (l slogSink) WithName(name string) LogSink {
	if l.name != "" {
		l.name += "/"
	}
	l.name += name
	return &l
}

func (l slogSink) WithValues(kvList ...interface{}) LogSink {
	l.handler = l.handler.WithAttrs(kvListToAttrs(kvList...))
	return &l
}

func kvListToAttrs(kvList ...interface{}) []slog.Attr {
	// We don't need the record itself, only its Add method.
	record := slog.NewRecord(time.Time{}, 0, "", 0)
	record.Add(kvList...)
	attrs := make([]slog.Attr, 0, record.NumAttrs())
	record.Attrs(func(attr slog.Attr) bool {
		attrs = append(attrs, attr)
		return true
	})
	return attrs
}
