package public

// GENERATED. DO NOT EDIT.
// TODO: move most of this logic into the runtime/public

{{- if $.Imports }}

import (
	{{- range $import := $.Imports }}
	{{$import.Name}} "{{$import.Path}}"
	{{- end }}
)
{{- end }}

{{- if $.Flag.Embed }}
// New middleware that serves embedded files
func New(fsys *overlay.FileSystem) Middleware {
	{{- range $embed := $.Embeds }}
	fsys.FileGenerator(`{{ $embed.Path }}`, &overlay.Embed{
		{{ if $embed.Data }}Data: []byte("{{ $embed.Data }}"),{{ end }}
	})
	{{- end }}
	return serve(http.FS(fsys), serveContent)
}
{{- else }}
// New middleware that serves files by reference
func New(fsys *overlay.Server) Middleware {
	{{/* Support default embeds (favicon.ico, default.css) */}}
	{{- range $embed := $.Embeds }}
	fsys.FileGenerator(`{{ $embed.Path }}`, &overlay.Embed{
		{{ if $embed.Data }}Data: []byte("{{ $embed.Data }}"),{{ end }}
	})
	{{- end }}
	return serve(http.FS(fsys), serveContent)
}
{{- end }}

type Middleware = middleware.Middleware

func serve(hfs http.FileSystem, serveContent func(w http.ResponseWriter, req *http.Request, name string, modtime time.Time, content io.ReadSeeker)) Middleware {
	return middleware.Function(func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			urlPath := r.URL.Path
			if r.Method != http.MethodGet || path.Ext(urlPath) == "" {
				next.ServeHTTP(w, r)
				return
			}
			file, err := hfs.Open(path.Join("public", urlPath))
			if err != nil {
				if errors.Is(err, fs.ErrNotExist) {
					next.ServeHTTP(w, r)
					return
				}
				http.Error(w, err.Error(), 500)
				return
			}
			stat, err := file.Stat()
			if err != nil {
				http.Error(w, err.Error(), 500)
				return
			}
			if stat.IsDir() {
				next.ServeHTTP(w, r)
				return
			}
			serveContent(w, r, urlPath, stat.ModTime(), file)
		})
	})
}

func serveContent(w http.ResponseWriter, req *http.Request, name string, modtime time.Time, content io.ReadSeeker) {
	http.ServeContent(w, req, name, modtime, content)
}

func serveGzipContent(w http.ResponseWriter, req *http.Request, name string, modtime time.Time, content io.ReadSeeker) {
	header := w.Header()
	header.Add("Content-Encoding", "gzip")
	header.Add("Vary", "Accept-Encoding")
	http.ServeContent(w, req, name, modtime, content)
}

