package sharedhost

import (
	"context"
	"crypto/tls"
	"net/url"

	"tildegit.org/tjp/gus"
)

// ReplaceTilde builds a middleware which substitutes a leading '~' in the request path.
//
// It makes the alteration to a copy of the request which is then passed into the
// wrapped Handler. This way middlewares outside of this one inspecting the request
// afterwards will see the original URL.
//
// Typically the replacement should end with a "/", so that the ~ ends up mapping to a
// particular directory on the filesystem. For instance with a replacement string of
// "users/", "domain.com/~jim/index.gmi" maps to "domain.com/users/jim/index.gmi".
func ReplaceTilde(replacement string) gus.Middleware {
	return func(inner gus.Handler) gus.Handler {
		return func(ctx context.Context, request *gus.Request) *gus.Response {
			if len(request.Path) > 1 && request.Path[0] == '/' && request.Path[1] == '~' {
				request = cloneRequest(request)
				request.Path = "/" + replacement + request.Path[2:]
			}

			return inner(ctx, request)
		}
	}
}

func cloneRequest(start *gus.Request) *gus.Request {
	next := &gus.Request{}
	*next = *start

	next.URL = &url.URL{}
	*next.URL = *start.URL

	if start.TLSState != nil {
		next.TLSState = &tls.ConnectionState{}
		*next.TLSState = *start.TLSState
	}

	return next
}