package server

import (
	"net/http"

	"github.com/mholt/caddy/config"
	"github.com/mholt/caddy/middleware"
)

// virtualHost represents a virtual host/server. While a Server
// is what actually binds to the address, a user may want to serve
// multiple sites on a single address, and this is what a
// virtualHost allows us to do.
type virtualHost struct {
	config     config.Config
	fileServer middleware.Handler
	stack      middleware.Handler
}

// buildStack builds the server's middleware stack based
// on its config. This method should be called last before
// ListenAndServe begins.
func (vh *virtualHost) buildStack() error {
	vh.fileServer = FileServer(http.Dir(vh.config.Root), []string{vh.config.ConfigFile})

	// TODO: We only compile middleware for the "/" scope.
	// Partial support for multiple location contexts already
	// exists at the parser and config levels, but until full
	// support is implemented, this is all we do right here.
	vh.compile(vh.config.Middleware["/"])

	return nil
}

// compile is an elegant alternative to nesting middleware function
// calls like handler1(handler2(handler3(finalHandler))).
func (vh *virtualHost) compile(layers []middleware.Middleware) {
	vh.stack = vh.fileServer // core app layer
	for i := len(layers) - 1; i >= 0; i-- {
		vh.stack = layers[i](vh.stack)
	}
}