<commit_before>package restacular

import (
	"fmt"
	"net/http"
	"net/url"
	"strings"
)

// User added route
type Route struct {
	HttpMethod string
	Pattern    string
	Func       func(*Response, *http.Request)
}

// The main object, only cares about route
type Application struct {
	routes []Route
}

// Internal type to get the result from a match
// Params will be added to the request by the dispatch method
type matchingRoute struct {
	route  Route
	params map[string]string
}

func NewApplication() *Application {
	return &Application{}
}

func (app *Application) SetRoutes(routes ...Route) {
	for i := range routes {
		// if pattern is not the root slash, remove trailing slash
		if len(routes[i].Pattern) > 1 && strings.HasSuffix(routes[i].Pattern, "/") {
			routes[i].Pattern = strings.TrimRight(routes[i].Pattern, "/")
		}
		app.routes = append(app.routes, routes[i])
	}
}

// Here for debug purpose
func (app *Application) ShowRoutes() {
	for i := range app.routes {
		fmt.Printf("%v\n", app.routes[i])
	}
}

// Finds if there is a match and get the params at the same time
func (app *Application) matchRequest(method, url string) *matchingRoute {
	for i := range app.routes {
		// Easy check on the method first
		if method != app.routes[i].HttpMethod {
			continue
		}

		// Getting each piece of the URL, no need to split on root / though
		currentSplitted := strings.Split(app.routes[i].Pattern[1:], "/")
		requestSplitted := strings.Split(url[1:], "/")

		if len(currentSplitted) != len(requestSplitted) {
			continue
		}

		matches := false
		params := make(map[string]string)

		for i := range currentSplitted {
			if strings.HasPrefix(currentSplitted[i], ":") {
				params[currentSplitted[i]] = requestSplitted[i]
				continue
			}
			if currentSplitted[i] != requestSplitted[i] {
				break
			}
			matches = true
		}

		if matches {
			return &matchingRoute{app.routes[i], params}
		}
	}

	return nil
}

// Returns an anonymous function that actually calls the user-defined
// view after setting the params in the URL.RawQuery (or a 404)
func (app *Application) dispatch() http.HandlerFunc {
	return func(resp http.ResponseWriter, req *http.Request) {
		requestPath := req.URL.Path
		requestMethod := req.Method<commit_msg>Add logging for incoming request<commit_after>package restacular

import (
	"fmt"
	"log"
	"net/http"
	"net/url"
	"strings"
)

// User added route
type Route struct {
	HttpMethod string
	Pattern    string
	Func       func(*Response, *http.Request)
}

// The main object, only cares about route
type Application struct {
	routes []Route
}

// Internal type to get the result from a match
// Params will be added to the request by the dispatch method
type matchingRoute struct {
	route  Route
	params map[string]string
}

func NewApplication() *Application {
	return &Application{}
}

func (app *Application) SetRoutes(routes ...Route) {
	for i := range routes {
		// if pattern is not the root slash, remove trailing slash
		if len(routes[i].Pattern) > 1 && strings.HasSuffix(routes[i].Pattern, "/") {
			routes[i].Pattern = strings.TrimRight(routes[i].Pattern, "/")
		}
		app.routes = append(app.routes, routes[i])
	}
}

// Here for debug purpose
func (app *Application) ShowRoutes() {
	for i := range app.routes {
		fmt.Printf("%v\n", app.routes[i])
	}
}

// Finds if there is a match and get the params at the same time
func (app *Application) matchRequest(method, url string) *matchingRoute {
	for i := range app.routes {
		// Easy check on the method first
		if method != app.routes[i].HttpMethod {
			continue
		}

		// Getting each piece of the URL, no need to split on root / though
		currentSplitted := strings.Split(app.routes[i].Pattern[1:], "/")
		requestSplitted := strings.Split(url[1:], "/")

		if len(currentSplitted) != len(requestSplitted) {
			continue
		}

		matches := false
		params := make(map[string]string)

		for i := range currentSplitted {
			if strings.HasPrefix(currentSplitted[i], ":") {
				params[currentSplitted[i]] = requestSplitted[i]
				continue
			}
			if currentSplitted[i] != requestSplitted[i] {
				break
			}
			matches = true
		}

		if matches {
			return &matchingRoute{app.routes[i], params}
		}
	}

	return nil
}

// Returns an anonymous function that actually calls the user-defined
// view after setting the params in the URL.RawQuery (or a 404)
func (app *Application) dispatch() http.HandlerFunc {
	return func(resp http.ResponseWriter, req *http.Request) {
		requestPath := req.URL.Path
		requestMethod := req.Method
		log.Println(requestMethod, requestPath)
{'fraction_non_alphanumeric': 0.1221978021978022, 'fraction_numerical': 0.0026373626373626374, 'mean_word_length': 3.6629098360655736, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4174189', 'n_tokens_mistral': 1562, 'n_tokens_neox': 1444, 'n_words': 450}