<commit_before>package router

import (
	"fmt"
	"log"
	"net/http"
	"reflect"

	"golang.org/x/net/websocket"
)

// RedirectError may be returned by PreFilter, PreItem or any
// Restful function and is intended for use for authentication
// checks or permission checks.
type RedirectError struct {
	Reason   string
	Location string
	Code     int
}

func (re RedirectError) Error() string {
	return fmt.Sprintf("Redirect to '%s' for: %s", re.Location, re.Reason)
}
func (re RedirectError) Redirect(w http.ResponseWriter, r *http.Request) {
	if re.Code == 0 {
		re.Code = 302
	}
	http.Redirect(w, r, re.Location, re.Code)
}
func ctrlName(ctrl interface{}) string {
	if adc, ok := ctrl.(autoDupeCtrl); ok {
		return adc.Name()
	}
	return reflect.TypeOf(ctrl).Name()
}

func callCtrl(w http.ResponseWriter, r *http.Request, l Leaf, p map[string]string, lg *log.Logger) (Controller, Result) {
	ctrl := l.Ctrl.Dupe()
	ctrl.SetRequestData(w, r)
	ctrl.SetID(p)
	ctrl.SetLogger(lg)
	name := ctrlName(ctrl)
	lg.Printf("Starting request for %s using %s.%s\n", r.URL.String(), name, l.Action)
	if l.SetContext {
		if sc, ok := ctrl.(contexter); ok {
			sc.SetContext(map[string]interface{}{})
		}
	}
	if l.PreFilter {
		if pf, ok := ctrl.(prefilter); ok {
			lg.Println("Running PreFilter")
			res := pf.PreFilter()
			if res != nil {
				lg.Printf("PreFilter returned %s\n", res.String())
				return nil, res
			}
		}
	}
	if l.PreItem && l.Item {
		if pi, ok := ctrl.(preitem); ok {
			lg.Println("Running PreItem")
			res := pi.PreItem()
			if res != nil {
				lg.Printf("PreItem returned %s\n", res.String())
				return nil, res
			}
		}
	}

	return ctrl, nil
}

type BaseController struct {
	http.ResponseWriter `dupe:"no"`
	Request             *http.Request `dupe:"no"`
	Log                 *log.Logger   `dupe:"no"`
	// The Cache is shared between all Controllers
	Cache map[string]interface{}
	// The Context will be a new map each request
	Context map[string]interface{}
	// URL Params
	ID map[string]string
}

func (bc *BaseController) SetRequestData(w http.ResponseWriter, r *http.Request) {
	bc.ResponseWriter = w
	bc.Request = r
}

func (bc *BaseController) SetLogger(l *log.Logger) {
	bc.Log = l
}

func (bc *BaseController) SetCache(c map[string]interface{}) {
	bc.Cache = c
}

func (bc *BaseController) SetContext(c map[string]interface{}) {
	bc.Context = c
}

func (bc *BaseController) SetID(p map[string]string) {
	bc.ID = p
}

type Controller interface {
	Path() string
	SetRequestData(http.ResponseWriter, *http.Request)
	SetID(map[string]string)
	SetLogger(*log.Logger)
}

type DupableController interface {<commit_msg>Add int id helper into base controller<commit_after>package router

import (
	"fmt"
	"log"
	"net/http"
	"reflect"
	"strconv"

	"golang.org/x/net/websocket"
)

// RedirectError may be returned by PreFilter, PreItem or any
// Restful function and is intended for use for authentication
// checks or permission checks.
type RedirectError struct {
	Reason   string
	Location string
	Code     int
}

func (re RedirectError) Error() string {
	return fmt.Sprintf("Redirect to '%s' for: %s", re.Location, re.Reason)
}
func (re RedirectError) Redirect(w http.ResponseWriter, r *http.Request) {
	if re.Code == 0 {
		re.Code = 302
	}
	http.Redirect(w, r, re.Location, re.Code)
}
func ctrlName(ctrl interface{}) string {
	if adc, ok := ctrl.(autoDupeCtrl); ok {
		return adc.Name()
	}
	return reflect.TypeOf(ctrl).Name()
}

func callCtrl(w http.ResponseWriter, r *http.Request, l Leaf, p map[string]string, lg *log.Logger) (Controller, Result) {
	ctrl := l.Ctrl.Dupe()
	ctrl.SetRequestData(w, r)
	ctrl.SetID(p)
	ctrl.SetLogger(lg)
	name := ctrlName(ctrl)
	lg.Printf("Starting request for %s using %s.%s\n", r.URL.String(), name, l.Action)
	if l.SetContext {
		if sc, ok := ctrl.(contexter); ok {
			sc.SetContext(map[string]interface{}{})
		}
	}
	if l.PreFilter {
		if pf, ok := ctrl.(prefilter); ok {
			lg.Println("Running PreFilter")
			res := pf.PreFilter()
			if res != nil {
				lg.Printf("PreFilter returned %s\n", res.String())
				return nil, res
			}
		}
	}
	if l.PreItem && l.Item {
		if pi, ok := ctrl.(preitem); ok {
			lg.Println("Running PreItem")
			res := pi.PreItem()
			if res != nil {
				lg.Printf("PreItem returned %s\n", res.String())
				return nil, res
			}
		}
	}

	return ctrl, nil
}

type BaseController struct {
	http.ResponseWriter `dupe:"no"`
	Request             *http.Request `dupe:"no"`
	Log                 *log.Logger   `dupe:"no"`
	// The Cache is shared between all Controllers
	Cache map[string]interface{}
	// The Context will be a new map each request
	Context map[string]interface{}
	// URL Params
	ID map[string]string
}

func (bc *BaseController) SetRequestData(w http.ResponseWriter, r *http.Request) {
	bc.ResponseWriter = w
	bc.Request = r
}

func (bc *BaseController) SetLogger(l *log.Logger) {
	bc.Log = l
}

func (bc *BaseController) SetCache(c map[string]interface{}) {
	bc.Cache = c
}

func (bc *BaseController) SetContext(c map[string]interface{}) {
	bc.Context = c
}

func (bc *BaseController) SetID(p map[string]string) {
	bc.ID = p
}

func (bc BaseController) IntID(name string) (int, bool) {
	sv, ok := bc.ID[name]
	if !ok {
		return 0, false
	}
	iv, err := strconv.Atoi(sv)
	return iv, err == nil
}

type Controller interface {
	Path() string
	SetRequestData(http.ResponseWriter, *http.Request)
	SetID(map[string]string)
	SetLogger(*log.Logger)
}

type DupableController interface {
{'fraction_non_alphanumeric': 0.14340729873464148, 'fraction_numerical': 0.001650467632495874, 'mean_word_length': 3.693631669535284, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '1249764', 'n_tokens_mistral': 2049, 'n_tokens_neox': 1952, 'n_words': 531}