You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: server.go
    path of file: ./repos/inbucket/pkg/server/web
    
    the code of the file until where you have to start completion: // Package web provides the plumbing for Inbucket's web GUI and RESTful API
package web

import (
	"context"
	"encoding/json"
	"expvar"
	"html/template"
	"net"
	"net/http"
	"net/http/pprof"
	"net/url"
	"os"
	"path/filepath"
	"time"

	"github.com/gorilla/mux"
	"github.com/inbucket/inbucket/v3/pkg/config"
	"github.com/inbucket/inbucket/v3/pkg/message"
	"github.com/inbucket/inbucket/v3/pkg/msghub"
	"github.com/inbucket/inbucket/v3/pkg/stringutil"
	"github.com/rs/zerolog/log"
)

var (
	// msgHub holds a reference to the message pub/sub system
	msgHub  *msghub.Hub
	manager message.Manager

	// Router is shared between httpd, webui and rest packages. It sends
	// incoming requests to the correct handler function
	Router = mux.NewRouter()

	rootConfig *config.Root
	server     *http.Server
	listener   net.Listener

	// ExpWebSocketConnectsCurrent tracks the number of open WebSockets
	ExpWebSocketConnectsCurrent = new(expvar.Int)
)

func init() {
	m := expvar.NewMap("http")
	m.Set("WebSocketConnectsCurrent", ExpWebSocketConnectsCurrent)
}

// Server defines an instance of the Web server.
type Server struct {
	// TODO Migrate global vars here.
	notify chan error // Notify on fatal error.
}

// NewServer sets up things for unit tests or the Start() method.
func NewServer(conf *config.Root, mm message.Manager, mh *msghub.Hub) *Server {
	rootConfig = conf

	// NewContext() will use this DataStore for the web handlers.
	msgHub = mh
	manager = mm

	// Redirect requests to / if there is a base path configured.
	prefix := stringutil.MakePathPrefixer(conf.Web.BasePath)
	redirectBase := prefix("/")
	if redirectBase != "/" {
		log.Info().Str("module", "web").Str("phase", "startup").Str("path", redirectBase).
			Msg("Base path configured")
		Router.Path("/").Handler(http.RedirectHandler(redirectBase, http.StatusFound))

		// Redirect prefix when missing trailing slash.
		Router.Path(prefix("")).Handler(http.RedirectHandler(redirectBase, http.StatusFound))
	}

	// Dynamic paths.
	log.Info().Str("module", "web").Str("phase", "startup").Str("path", conf.Web.UIDir).
		Msg("Web UI content mapped")
	Router.Handle(prefix("/debug/vars"), expvar.Handler())
	if conf.Web.PProf {
		Router.HandleFunc(prefix("/debug/pprof/cmdline"), pprof.Cmdline)
		Router.HandleFunc(prefix("/debug/pprof/profile"), pprof.Profile)
		Router.HandleFunc(prefix("/debug/pprof/symbol"), pprof.Symbol)
		Router.HandleFunc(prefix("/debug/pprof/trace"), pprof.Trace)
		Router.PathPrefix(prefix("/debug
    
func NewServer(conf *config.Root, mm message.Manager, mh *msghub.Hub) *Server {
	rootConfig = conf

	// NewContext() will use this DataStore for the web handlers.
	msgHub = mh
	manager = mm

	// Redirect requests to / if there is a base path configured.
	prefix := stringutil.MakePathPrefixer(conf.Web.BasePath)
	redirectBase := prefix("/")
	if redirectBase != "/" {
		log.Info().Str("module", "web").Str("phase", "startup").Str("path", redirectBase).
			Msg("Base path configured")
		Router.Path("/").Handler(http.RedirectHandler(redirectBase, http.StatusFound))

		// Redirect prefix when missing trailing slash.
		Router.Path(prefix("")).Handler(http.RedirectHandler(redirectBase, http.StatusFound))
	}

	// Dynamic paths.
	log.Info().Str("module", "web").Str("phase", "startup").Str("path", conf.Web.UIDir).
		Msg("Web UI content mapped")
	Router.Handle(prefix("/debug/vars"), expvar.Handler())
	if conf.Web.PProf {
		Router.HandleFunc(prefix("/debug/pprof/cmdline"), pprof.Cmdline)
		Router.HandleFunc(prefix("/debug/pprof/profile"), pprof.Profile)
		Router.HandleFunc(prefix("/debug/pprof/symbol"), pprof.Symbol)
		Router.HandleFunc(prefix("/debug/pprof/trace"), pprof.Trace)
		Router.PathPrefix(prefix("/debug/pprof/")).HandlerFunc(pprof.Index)
		log.Warn().Str("module", "web").Str("phase", "startup").
			Msg("Go pprof tools installed to " + prefix("/debug/pprof"))
	}

	// Static paths.
	Router.PathPrefix(prefix("/static")).Handler(
		http.StripPrefix(prefix("/"), http.FileServer(http.Dir(conf.Web.UIDir))))
	Router.Path(prefix("/favicon.png")).Handler(
		fileHandler(filepath.Join(conf.Web.UIDir, "favicon.png")))

	// Parse index.html template, allowing for configuration to be passed to the SPA.
	indexPath := filepath.Join(conf.Web.UIDir, "index.html")
	indexTmpl, err := template.ParseFiles(indexPath)
	if err != nil {
		msg := "Failed to parse HTML template"
		cwd, _ := os.Getwd()
		log.Error().
			Str("module", "web").
			Str("phase", "startup").
			Str("path", indexPath).
			Str("cwd", cwd).
			Err(err).
			Msg(msg)
		// Create a dummy template to allow tests to pass.
		indexTmpl, _ = template.New("index.html").Parse(msg)
	}

	// SPA managed paths.
	spaHandler := cookieHandler(appConfigCookie(conf.Web),
		spaTemplateHandler(indexTmpl, prefix("/")))
	Router.Path(prefix("/")).Handler(spaHandler)
	Router.Path(prefix("/monitor")).Handler(spaHandler)
	Router.Path(prefix("/status")).Handler(spaHandler)
	Router.PathPrefix(prefix("/m/")).Handler(spaHandler)

	// Error handlers.
	Router.NotFoundHandler = noMatchHandler(
		http.StatusNotFound, "No route matches URI path")
	Router.MethodNotAllowedHandler = noMatchHandler(
		http.StatusMethodNotAllowed, "Method not allowed for URI path")

	s := &Server{
		notify: make(chan error, 1),
	}

	return s
}