package twitchhttp

import (
	"context"
	"log"

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

// Logger is a logging interface which offers the ability to log, debug log, and do so with
// dimensions attached to the context, like request ID.
type Logger interface {
	DebugCtx(ctx goctx.Context, params ...interface{})
	Debug(params ...interface{})
	LogCtx(ctx goctx.Context, params ...interface{})
	Log(params ...interface{})
}

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{}) {
	log.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)
}
