package logz

import (
	"fmt"
	"io"
	"log/slog"
	"path/filepath"
	"sync"

	"k8s.io/apimachinery/pkg/util/sets"
)

type LogValuerFunc func() slog.Value

func (f LogValuerFunc) LogValue() slog.Value {
	return f()
}

func LazyValue(key string, val func() slog.Value) slog.Attr {
	return slog.Any(key, LogValuerFunc(val))
}

func Strings(key string, val []string) slog.Attr {
	return LazyValue(key, func() slog.Value {
		// don't expand val into a vararg. Use as a single argument to ensure spaces are added between elements.
		return slog.StringValue(fmt.Sprint(val))
	})
}

func StringSet(key string, val sets.Set[string]) slog.Attr {
	return LazyValue(key, func() slog.Value {
		// don't expand val into a vararg. Use as a single argument to ensure spaces are added between elements.
		return slog.StringValue(fmt.Sprint(val.UnsortedList()))
	})
}

func TrimSourceFilePath(attr slog.Attr) slog.Attr {
	switch attr.Key {
	case slog.SourceKey:
		s, ok := attr.Value.Any().(*slog.Source)
		if ok {
			s.File = filepath.Base(s.File)
		}
		return attr
	default:
		return attr
	}
}

// LockedWriter serializes Write calls.
type LockedWriter struct {
	io.Writer
	mu sync.Mutex
}

func (w *LockedWriter) Write(data []byte) (int, error) {
	w.mu.Lock()
	defer w.mu.Unlock()
	return w.Writer.Write(data)
}
