package logger

import (
	"net/http"
	"time"

	"go.uber.org/zap/zapcore"
)

// Request wraps *http.Request to provide log marshaling functionality.
type Request struct {
	Request   *http.Request
	Status    int
	StartTime time.Time
	ID        string
}

func (r Request) MarshalLogObject(enc zapcore.ObjectEncoder) error {
	enc.AddString("method", r.Request.Method)
	enc.AddString("url", r.Request.URL.String())
	enc.AddDuration("duration", time.Since(r.StartTime))
	enc.AddInt("status", r.Status)
	enc.AddString("ID", r.ID)

	return enc.AddObject("headers", Headers{headers: r.Request.Header})
}

type Headers struct {
	headers http.Header
}

func (h Headers) MarshalLogObject(enc zapcore.ObjectEncoder) error {
	for k := range h.headers {
		// don't log potentially sensitive information
		if k == "Cookie" || k == "Authorization" {
			continue
		}
		err := enc.AddArray(k, HeaderValue{values: h.headers[k]})
		if err != nil {
			return err
		}
	}
	return nil
}

type HeaderValue struct {
	values []string
}

func (hv HeaderValue) MarshalLogArray(enc zapcore.ArrayEncoder) error {
	for _, v := range hv.values {
		enc.AppendString(v)
	}
	return nil
}
