package clog

import (
	"fmt"
	"log"

	"code.justin.tv/common/chitin/internal/trace"
	"golang.org/x/net/context"
)

// A Logger formats messages and routes them to the appropriate stream or
// file.
type Logger interface {
	Printf(format string, v ...interface{})
}

// A LogOpt sets options on a Logger, returning a LogOpt that can revert the
// changes.
type LogOpt func(l *logger) (revert LogOpt)

// SetConsumer returns a LogOpt that can be used to change the destination of
// messages sent to a Logger.
func SetConsumer(fn func(string)) LogOpt {
	return func(l *logger) LogOpt {
		prev := l.consumer
		l.consumer = fn
		return SetConsumer(prev)
	}
}

type logger struct {
	prefix   string
	consumer func(string)
}

func (l *logger) Printf(format string, v ...interface{}) {
	l.consumer(l.prefix + fmt.Sprintf(format, v...))
}

// Log generates a new Logger. Messages sent to the Logger will be prefixed
// with a logfmt-formatted version of the Trace context.
func Log(ctx context.Context, options ...LogOpt) Logger {
	l := &logger{
		prefix:   trace.Logfmt(ctx) + " ",
		consumer: func(s string) { log.Print(s) },
	}
	for _, opt := range options {
		opt(l)
	}
	return l
}
