package twitchserver

import (
	"context"
	"log"
	"os"

	goctx "golang.org/x/net/context"
)

var logger Logger = log.New(os.Stderr, "", log.LstdFlags)

// Logger is subset of golang standard logger we use.
type Logger interface {
	Print(args ...interface{})
	Printf(format string, args ...interface{})
	Println(args ...interface{})
}

// SetLogger sets the logger that is used.
// Isn't mutex protected so only call from init() functions.
func SetLogger(l Logger) {
	logger = l
}

type defaultLogger struct{}

func (l *defaultLogger) DebugCtx(ctx goctx.Context, params ...interface{}) {
	return
}

func (l *defaultLogger) Debug(params ...interface{}) {
	return
}

func (l *defaultLogger) LogCtx(ctx goctx.Context, params ...interface{}) {
	logger.Println(params)
}

func (l *defaultLogger) Log(params ...interface{}) {
	l.LogCtx(goctx.Background(), params)
}

// ctxDimensions can propagate log dimensions inside a context object
type ctxDimensions struct {
	dimensionKey interface{}
}

// From returns the dimensions currently set inside a context object
func (c *ctxDimensions) From(ctx goctx.Context) []interface{} {
	existing := ctx.Value(c.dimensionKey)
	if existing == nil {
		return []interface{}{}
	}
	return existing.([]interface{})
}

// Append returns a new context that appends vals as dimensions for logging
func (c *ctxDimensions) Append(ctx goctx.Context, vals ...interface{}) goctx.Context {
	if len(vals) == 0 {
		return ctx
	}
	if len(vals)%2 != 0 {
		panic("Expected even number of values")
	}
	existing := c.From(ctx)
	newArr := make([]interface{}, 0, len(existing)+len(vals))
	newArr = append(newArr, existing...)
	newArr = append(newArr, vals...)
	return context.WithValue(ctx, c.dimensionKey, newArr)
}
