// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
// 🤖 Github Repository: https://github.com/gofiber/fiber
// 📌 API Documentation: https://docs.gofiber.io

package fiber

import (
	
	
)

// Group struct
type Group struct {
	app             *App
	parentGroup     *Group
	name            string
	anyRouteDefined bool

	Prefix string
}

// Name Assign name to specific route or group itself.
//
// If this method is used before any route added to group, it'll set group name and OnGroupNameHook will be used.
// Otherwise, it'll set route name and OnName hook will be used.
func ( *Group) ( string) Router {
	if .anyRouteDefined {
		.app.Name()

		return 
	}

	.app.mutex.Lock()
	if .parentGroup != nil {
		.name = .parentGroup.name + 
	} else {
		.name = 
	}

	if  := .app.hooks.executeOnGroupNameHooks(*);  != nil {
		panic()
	}
	.app.mutex.Unlock()

	return 
}

// Use registers a middleware route that will match requests
// with the provided prefix (which is optional and defaults to "/").
//
//	app.Use(func(c *fiber.Ctx) error {
//	     return c.Next()
//	})
//	app.Use("/api", func(c *fiber.Ctx) error {
//	     return c.Next()
//	})
//	app.Use("/api", handler, func(c *fiber.Ctx) error {
//	     return c.Next()
//	})
//
// This method will match all HTTP verbs: GET, POST, PUT, HEAD etc...
func ( *Group) ( ...interface{}) Router {
	var  string
	var  []string
	var  []Handler

	for  := 0;  < len(); ++ {
		switch arg := [].(type) {
		case string:
			 = 
		case []string:
			 = 
		case Handler:
			 = append(, )
		default:
			panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf()))
		}
	}

	if len() == 0 {
		 = append(, )
	}

	for ,  := range  {
		.app.register(methodUse, getGroupPath(.Prefix, ), , ...)
	}

	if !.anyRouteDefined {
		.anyRouteDefined = true
	}

	return 
}

// Get registers a route for GET methods that requests a representation
// of the specified resource. Requests using GET should only retrieve data.
func ( *Group) ( string,  ...Handler) Router {
	.Add(MethodHead, , ...)
	return .Add(MethodGet, , ...)
}

// Head registers a route for HEAD methods that asks for a response identical
// to that of a GET request, but without the response body.
func ( *Group) ( string,  ...Handler) Router {
	return .Add(MethodHead, , ...)
}

// Post registers a route for POST methods that is used to submit an entity to the
// specified resource, often causing a change in state or side effects on the server.
func ( *Group) ( string,  ...Handler) Router {
	return .Add(MethodPost, , ...)
}

// Put registers a route for PUT methods that replaces all current representations
// of the target resource with the request payload.
func ( *Group) ( string,  ...Handler) Router {
	return .Add(MethodPut, , ...)
}

// Delete registers a route for DELETE methods that deletes the specified resource.
func ( *Group) ( string,  ...Handler) Router {
	return .Add(MethodDelete, , ...)
}

// Connect registers a route for CONNECT methods that establishes a tunnel to the
// server identified by the target resource.
func ( *Group) ( string,  ...Handler) Router {
	return .Add(MethodConnect, , ...)
}

// Options registers a route for OPTIONS methods that is used to describe the
// communication options for the target resource.
func ( *Group) ( string,  ...Handler) Router {
	return .Add(MethodOptions, , ...)
}

// Trace registers a route for TRACE methods that performs a message loop-back
// test along the path to the target resource.
func ( *Group) ( string,  ...Handler) Router {
	return .Add(MethodTrace, , ...)
}

// Patch registers a route for PATCH methods that is used to apply partial
// modifications to a resource.
func ( *Group) ( string,  ...Handler) Router {
	return .Add(MethodPatch, , ...)
}

// Add allows you to specify a HTTP method to register a route
func ( *Group) (,  string,  ...Handler) Router {
	.app.register(, getGroupPath(.Prefix, ), , ...)
	if !.anyRouteDefined {
		.anyRouteDefined = true
	}

	return 
}

// Static will create a file server serving static files
func ( *Group) (,  string,  ...Static) Router {
	.app.registerStatic(getGroupPath(.Prefix, ), , ...)
	if !.anyRouteDefined {
		.anyRouteDefined = true
	}

	return 
}

// All will register the handler on all HTTP methods
func ( *Group) ( string,  ...Handler) Router {
	for ,  := range .app.config.RequestMethods {
		_ = .Add(, , ...)
	}
	return 
}

// Group is used for Routes with common prefix to define a new sub-router with optional middleware.
//
//	api := app.Group("/api")
//	api.Get("/users", handler)
func ( *Group) ( string,  ...Handler) Router {
	 = getGroupPath(.Prefix, )
	if len() > 0 {
		.app.register(methodUse, , , ...)
	}

	// Create new group
	 := &Group{Prefix: , app: .app, parentGroup: }
	if  := .app.hooks.executeOnGroupHooks(*);  != nil {
		panic()
	}

	return 
}

// Route is used to define routes with a common prefix inside the common function.
// Uses Group method to define new sub-router.
func ( *Group) ( string,  func( Router),  ...string) Router {
	// Create new group
	 := .Group()
	if len() > 0 {
		.Name([0])
	}

	// Define routes
	()

	return 
}