package main

import (
	"log"
	"net/http"
	"os"
	"path"
	"strings"
)

type submissionHandler func(w http.ResponseWriter, r *http.Request, sURL []string)

type submissionChecker struct{
	kind     string
	next     submissionHandler
}

type submissionTeamHandler func(w http.ResponseWriter, r *http.Request, team string, sURL []string)

type submissionTeamChecker struct{
	kind     string
	next     submissionTeamHandler
	teamsDir string
}

func (c submissionChecker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if addr := r.Header.Get("X-Forwarded-For"); addr != "" {
		r.RemoteAddr = addr
	}
	log.Printf("%s \"%s %s\" => %s [%s]\n", r.RemoteAddr, r.Method, r.URL.Path, c.kind, r.UserAgent())

	w.Header().Set("Content-Type", "application/json")

	// Check request type and size
	if r.Method != "POST" {
		http.Error(w, "{\"errmsg\":\"Requête invalide.\"}", http.StatusBadRequest)
		return
	} else if r.ContentLength < 0 || r.ContentLength > 2047 {
		http.Error(w, "{\"errmsg\":\"Requête trop longue ou de taille inconnue\"}", http.StatusRequestEntityTooLarge)
		return
	}

	// Extract URL arguments
	var sURL = strings.Split(r.URL.Path, "/")

	c.next(w, r, sURL)
}

func (c submissionTeamChecker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	submissionChecker{c.kind, func(w http.ResponseWriter, r *http.Request, sURL []string){
		if len(sURL) < 1 {
			http.Error(w, "{\"errmsg\":\"Arguments manquants.\"}", http.StatusBadRequest)
			return
		}
		team := sURL[0]

		// Check team validity and existance
		if len(team) < 1 || team == "public" {
			log.Println("INVALID TEAM:", team)
			http.Error(w, "{\"errmsg\":\"Équipe inexistante.\"}", http.StatusBadRequest)
			return
		} else if _, err := os.Stat(path.Join(c.teamsDir, team)); os.IsNotExist(err) {
			log.Println("UNKNOWN TEAM:", team)
			http.Error(w, "{\"errmsg\":\"Équipe inexistante.\"}", http.StatusBadRequest)
			return
		}

		c.next(w, r, team, sURL[1:])
	}}.ServeHTTP(w, r)
}
