package middleware

import "net/http"

type (
	// Interceptor intercepts an HTTP handler invocation, it is passed both
	// response writer and request which after interception can be passed
	// onto the handler function.
	Interceptor func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)

	// HandlerFunc builds on top of http.HandlerFunc, and exposes API to
	// intercept with Interceptor. This allows building complex long chains
	// without complicated struct manipulation.
	HandlerFunc http.HandlerFunc

	// Chain is a collection of interceptors that will be invoked in there
	// index order.
	Chain []Interceptor

	// Skipper is a requests checker for middleware configurations. true
	// return force middleware to skip any actions with current request.
	Skipper func(r *http.Request) bool
)

var DefaultSkipper Skipper = func(_ *http.Request) bool { return false }

// Intercept returns back a continuation that will call install middleware to
// intercept the continuation call.
func (hf HandlerFunc) Intercept(i Interceptor) HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		i(w, r, http.HandlerFunc(hf))
	}
}

// Handler allows hooking multiple middleware in single call.
func (c Chain) Handler(hf http.HandlerFunc) http.Handler {
	current := HandlerFunc(hf)

	for i := len(c) - 1; i >= 0; i-- {
		current = current.Intercept(c[i])
	}

	return http.HandlerFunc(current)
}
