package organize

import (
	"git.nobla.cn/golang/kos/entry/http"
	"git.nobla.cn/golang/moto/internal/organize/passport"
	"git.nobla.cn/golang/moto/internal/organize/types"
	"os"
	"strings"
)

var (
	allowUris []string

	CookieName = "MOTO_US"
)

func init() {
	allowUris = make([]string, 0, 10)
}

func AllowUri(s string) {
	allowUris = append(allowUris, s)
}

func isAllowed(uriPath string) bool {
	for _, s := range allowUris {
		sl := len(s)
		if sl <= 0 {
			continue
		}
		if s[sl-1] == '*' {
			if strings.HasPrefix(uriPath, s[:sl-1]) {
				return true
			}
		} else if s == uriPath {
			return true
		}
	}
	return false
}

func AuthMiddleware(next http.HandleFunc) http.HandleFunc {
	return func(ctx *http.Context) (err error) {
		if isAllowed(ctx.Request().URL.Path) {
			return next(ctx)
		}
		var (
			pos         int
			accessToken string
			ui          *http.Userinfo
			tk          *types.Tokenize
		)
		if accessToken = ctx.Query("access_token"); accessToken != "" {
			goto __end
		}
		if accessToken = ctx.GetCookieValue(CookieName); accessToken != "" {
			goto __end
		}
		if accessToken = ctx.Request().Header.Get("Authorization"); accessToken != "" {
			goto __end
		}
	__end:
		accessToken = strings.TrimSpace(accessToken)
		if pos = strings.IndexByte(accessToken, ' '); pos > -1 {
			accessToken = accessToken[pos+1:]
		}
		if tk, err = passport.Validate(ctx.Context(), accessToken); err != nil {
			err = ctx.Error(http.ErrAccessDenied, "access denied")
			err = os.ErrPermission
			return
		}
		ui = &http.Userinfo{
			ID:   tk.UID,
			Name: tk.Name,
		}
		ui.Set("token", tk.Token)
		ctx.SetUser(ui)
		return next(ctx)
	}
}