package main

import (
	"net/http"
	"strings"

	"github.com/gorilla/mux"
	"github.com/zeevdiukman/zprox/internal/auth"
	"github.com/zeevdiukman/zprox/internal/config"
)

func BuildRoutes(routerData *config.Router, handlers map[string]func(string, string) http.HandlerFunc, epr *mux.Router) {
	routerData.Routes.ForEach(func(routeID string, route *config.Route) string {
		blockedRoutes := map[string]string{}
		route.ForEachRule(func(routeID string, ruleName, ruleValue string) string {
			if ruleName == "!Host" || ruleName == "!PathPrefix" || ruleName == "!Path" || ruleName == "!Headers" {
				blockedRoutes[routeID] = ruleValue
				return "break"
			}
			return ""

		})

		if len(blockedRoutes) > 0 {
			nrBlock := epr.NewRoute().Name(routeID + "_block")
			route.ForEachRule(func(routeID string, ruleName, ruleValue string) string {
				switch ruleName {
				case "!Host":
					{
						nrBlock = nrBlock.Host(ruleValue)

					}
				case "!PathPrefix":
					{
						nrBlock = nrBlock.PathPrefix(ruleValue)

					}
				case "!Path":
					{
						nrBlock = nrBlock.Path(ruleValue)

					}
				case "!Headers":
					{
						ruleValue := strings.Split(ruleValue, ":")
						nrBlock = nrBlock.Headers(ruleValue[0], ruleValue[1])
					}
				default:

				}
				return ""
			})
			nrBlock.HandlerFunc(http.NotFound)
		}

		nr := epr.NewRoute().Name(routeID)
		route.ForEachRule(func(routeID string, ruleName, ruleValue string) string {
			switch ruleName {
			case "Host":
				{
					nr = nr.Host(ruleValue)

				}
			case "PathPrefix":
				{
					nr = nr.PathPrefix(ruleValue)

				}
			case "Path":
				{
					nr = nr.Path(ruleValue)

				}
			case "Headers":
				{
					ruleValue := strings.Split(ruleValue, ":")
					nr = nr.Headers(ruleValue[0], ruleValue[1])
				}
			default:
			}

			return ""
		})

		serviceURL := config.Data.Services[routerData.Service]
		handler := handlers[routerData.EntryPoint]

		h := handler(serviceURL, routeID)
		nr.HandlerFunc(h)
		return ""
	})
}

func buildAuthRoutes(epmr *mux.Router, routerData *config.Router) {
	if routerData.Auth.Enabled {
		var authSubrouter *mux.Router
		authConfig := config.Data.AuthMap[routerData.Auth.Provider]
		authPrefix := authConfig.Paths.Prefix
		// LoginPath := authConfig.Paths.Login
		logoutPath := authConfig.Paths.Logout
		callbackPath := authConfig.Paths.Callback
		// PostLogoutPath := authConfig.Paths.PostLogout
		authRoute := epmr.NewRoute().Name(routerData.Name)
		routerData.Routes.ForEach(func(routeID string, v *config.Route) string {
			if isRouteProtected, ok := v.Rule["Auth"]; (ok && isRouteProtected != "false") || !ok {
				if host, ok := v.Rule["Host"]; ok && host != "" {
					authSubrouter = authRoute.Host(host).PathPrefix(authPrefix + "/").Subrouter()
				} else {
					authSubrouter = authRoute.PathPrefix(authPrefix + "/").Subrouter()
				}
				authSubrouter.Use(func(next http.Handler) http.Handler {
					return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
						next.ServeHTTP(w, r)
					})
				})
				// authSubrouter.Path(LoginPath).HandlerFunc(auth.LoginHandler(authConfig,routerData))
				authSubrouter.Path(logoutPath).HandlerFunc(auth.LogoutHandler(authConfig, routerData))
				authSubrouter.Path(callbackPath).HandlerFunc(auth.CallbackHandler(authConfig, routerData))
				// authSubrouter.Path(PostLogoutPath).HandlerFunc(auth.PostLogoutHandler(authConfig, routerData))
				return "break"
			}
			return ""
		})
	}
}

// func buildAuthRoutes(epmr *mux.Router, routerData *config.Router, handlers map[string]func(string, string) http.HandlerFunc) {
// 	if routerData.Auth.Enabled {

// 		host := ""

// 		routerData.Routes.ForEach(func(routeID string, v *config.Route) string {
// 			if isRouteProtected, ok := v.Rule["Auth"]; (ok && isRouteProtected != "false") || !ok {
// 				if _, ok := v.Rule["Host"]; ok {
// 					host = v.Rule["Host"]

// 					return "break"
// 				}
// 			}
// 			return ""
// 		})
// 		if host != "" {
// 			dump.P(host)
// 			// var r *mux.Router
// 			authConfig := config.Data.AuthMap[routerData.Auth.Provider]
// 			authPrefix := authConfig.Paths.Prefix
// 			// loginPath := authConfig.Paths.Login
// 			// logoutPath := authConfig.Paths.Logout
// 			callbackPath := authConfig.Paths.Callback
// 			// postLogoutPath := authConfig.Paths.PostLogout
// 			authRoute := epmr.NewRoute().Name(routerData.Name)
// 			// authSubrouter = authRoute.Host(host).PathPrefix(authPrefix).Subrouter()
// 			authRoute = authRoute.PathPrefix(authPrefix)
// 			authRoute = authRoute.Path("/callback")
// 			authRoute.Handler(auth.CallbackHandler(authConfig, routerData))
// 			handler := handlers[routerData.EntryPoint]
// 			h := handler(serviceURL, routeID)
// 			nr.HandlerFunc(h)
// 			// authSubrouter.Path(loginPath).HandlerFunc(auth.LoginHandler(authConfig, routerData))
// 			// authSubrouter.Path(logoutPath).HandlerFunc(auth.LogoutHandler(authConfig, routerData))
// 			// authSubrouter.Path(callbackPath).HandlerFunc(auth.CallbackHandler(authConfig, routerData))
// 			// authSubrouter.Path(postLogoutPath).HandlerFunc(auth.PostLogoutHandler(authConfig, routerData))
// 		}

// 		// if isRouteProtected, ok := route.Rule["Auth"]; (ok && isRouteProtected != "false") || !ok {
// 		// if host, ok := v.Rule["Host"]; ok && host != "" {
// 		// dump.P(authPrefix)
// 		// return "break"
// 		// }
// 		// } else {
// 		// 	authSubrouter = authRoute.PathPrefix(authPrefix).Subrouter()
// 		// }
// 		// authSubrouter.Use(func(next http.Handler) http.Handler {
// 		// 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

// 		// 		next.ServeHTTP(w, r)
// 		// 	})
// 		// serviceURL := config.Data.Services[routerData.Service]

// 		// handler := handlers[routerData.EntryPoint]
// 		// h := handler(serviceURL, routeID)
// 		// nr.HandlerFunc(h)

// 		// 	return ""
// 		// })

// 		// return "break"
// 		// }
// 		// return ""
// 		// })
// 	}
// }

// func buildAuthRoutes(epmr *mux.Router, routerData *config.Router) {
// 	if routerData.Auth.Enabled {
// 		var authSubrouter *mux.Router
// 		authConfig := config.Data.AuthMap[routerData.Auth.Provider]
// 		authPrefix := authConfig.Paths.Prefix
// 		LoginPath := authConfig.Paths.Login
// 		LogoutPath := authConfig.Paths.Logout
// 		CallbackPath := authConfig.Paths.Callback
// 		PostLogoutPath := authConfig.Paths.PostLogout
// 		authRoute := epmr.NewRoute().Name(routerData.Name)
// 		routerData.Routes.ForEach(func(routeID string, v *config.Route) string {
// 			if isRouteProtected, ok := v.Rule["Auth"]; (ok && isRouteProtected != "false") || !ok {
// 				if host, ok := v.Rule["Host"]; ok && host != "" {
// 					authSubrouter = authRoute.Host(host).PathPrefix(authPrefix + "/").Subrouter()
// 				} else {
// 					authSubrouter = authRoute.PathPrefix(authPrefix + "/").Subrouter()
// 				}
// 				authSubrouter.Use(func(next http.Handler) http.Handler {
// 					return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 						next.ServeHTTP(w, r)
// 					})
// 				})
// 				authSubrouter.Path(LoginPath).HandlerFunc(auth.LoginHandler(authConfig))
// 				authSubrouter.Path(LogoutPath).HandlerFunc(auth.LogoutHandler(authConfig, routerData))
// 				authSubrouter.Path(CallbackPath).HandlerFunc(auth.CallbackHandler(authConfig))
// 				authSubrouter.Path(PostLogoutPath).HandlerFunc(auth.PostLogoutHandler(authConfig, routerData))
// 				return "break"
// 			}
// 			return ""
// 		})
// 	}
// }
