package main

import (
	"encoding/base64"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"html"
	"io/ioutil"
	"log"
	"math/rand"
	"os"
	"path"

	"srs.epita.fr/fic-server/libfic"
)

var (
	allowRegistration = false
	canJoinTeam       = false
	denyTeamCreation  = false
)

type uTeamRegistration struct {
	TeamName string
	JTeam    int64
	Members  []fic.Member
}

func registrationProcess(id string, team *fic.Team, members []fic.Member, team_id string) {
	for _, m := range members {
		// Force Id to 0, as it shouldn't have been defined yet
		m.Id = 0
		if err := team.GainMember(&m); err != nil {
			log.Println("[WRN] Unable to add member (", m, ") to team (", team, "):", err)
		}
	}

	teamDirPath := fmt.Sprintf("%d", team.Id)

	// Create team directories into TEAMS
	if err := os.MkdirAll(path.Join(TeamsDir, teamDirPath), 0751); err != nil {
		log.Println(id, "[ERR]", err)
	}
	if err := os.Symlink(teamDirPath, path.Join(TeamsDir, team_id)); err != nil {
		log.Println(id, "[ERR]", err)
	}

	appendGenQueue(fic.GenStruct{Id: id, Type: fic.GenTeam, TeamId: team.Id})
	appendGenQueue(fic.GenStruct{Id: id, Type: fic.GenTeams})
}

func treatRegistration(pathname string, team_id string) {
	// Generate a unique identifier to follow the request in logs
	bid := make([]byte, 5)
	binary.LittleEndian.PutUint32(bid, rand.Uint32())
	id := "[" + base64.StdEncoding.EncodeToString(bid) + "]"
	log.Println(id, "New registration receive", pathname)

	var nTeam uTeamRegistration

	if !allowRegistration {
		log.Printf("%s [ERR] Registration received, whereas disabled. Skipped.\n", id)
	} else if cnt_raw, err := ioutil.ReadFile(pathname); err != nil {
		log.Printf("%s [ERR] %s\n", id, err)
	} else if err := json.Unmarshal(cnt_raw, &nTeam); err != nil {
		log.Printf("%s [ERR] %s\n", id, err)
	} else if nTeam.JTeam > 0 {
		if !canJoinTeam {
			log.Printf("%s [ERR] Join team received, whereas disabled. Skipped.\n", id)
		} else if len(nTeam.Members) != 1 {
			log.Printf("%s [ERR] Join team received, with incorrect member length: %d. Skipped.\n", id, len(nTeam.Members))
		} else if team, err := fic.GetTeam(nTeam.JTeam); err != nil {
			log.Printf("%s [ERR] Unable to join registered team %d: %s\n", id, nTeam.JTeam, err)
		} else {
			registrationProcess(id, team, nTeam.Members, team_id)

			if err := os.Remove(pathname); err != nil {
				log.Printf("%s [WRN] %s\n", id, err)
			}
		}
	} else if denyTeamCreation {
		log.Printf("%s [ERR] Registration received, whereas team creation denied. Skipped.\n", id)
	} else if validTeamName(nTeam.TeamName) {
		if team, err := fic.CreateTeam(nTeam.TeamName, fic.HSL{H: rand.Float64(), L: 1, S: 0.5}.ToRGB(), ""); err != nil {
			log.Printf("%s [ERR] Unable to register new team %s: %s\n", id, nTeam.TeamName, err)
		} else {
			registrationProcess(id, team, nTeam.Members, team_id)

			if err := os.Remove(pathname); err != nil {
				log.Printf("%s [WRN] %s\n", id, err)
			}
			if _, err := fic.NewEvent(fmt.Sprintf("Souhaitons bonne chance à l'équipe <strong>%s</strong> qui vient de nous rejoindre&#160;!", html.EscapeString(team.Name)), "info"); err != nil {
				log.Printf("%s [WRN] Unable to create event: %s\n", id, err)
			}

			appendGenQueue(fic.GenStruct{Id: id, Type: fic.GenEvents})
		}
	}
}
