Skip to content
Snippets Groups Projects
poll.go 6.20 KiB
package poll

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"

	"forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/database"
	"github.com/gorilla/mux"
)

type Poll struct {
	Year     int    `json:"year"`
	Month    int    `json:"month"`
	Question string `json:"question"`
	Link     string `json:"link"`
}

// GetAllPolls godoc
// @Summary List all polls
// @Description Get details of all polls
// @Tags poll
// @Produce  json
// @Success 200 {array} Poll
// @Router /api/admin/poll [get]
func GetAllPolls(w http.ResponseWriter, r *http.Request) {
	Questions := database.GetAll("question")
	Links := database.GetAll("link")

	var poll []Poll

	for _, question := range Questions {
		linkExists := false
		for _, link := range Links {
			if question.Year == link.Year && question.Month == link.Month {
				poll = append(poll, Poll{question.Year, question.Month, question.Content, link.Content})
				linkExists = true
				break
			}
		}
		if !linkExists {
			poll = append(poll, Poll{question.Year, question.Month, question.Content, ""})
		}
	}

	w.Header().Set("Content-Type", "application/json")
	log.Println(poll)
	json.NewEncoder(w).Encode(poll)
	log.Printf("| get all polls | %v", r.RemoteAddr)
}

// GetSinglePoll godoc
// @Summary Get details of a specific poll
// @Description Get details of a specific poll
// @Tags poll
// @Produce  json
// @Success 200 {object} Poll
// @Param year path int true "Year of the poll"
// @Param month path int true "Month of the poll"
// @Router /api/admin/poll/{year}/{month} [get]
func GetSinglePoll(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	yearStr := vars["year"]
	monthStr := vars["month"]

	if yearStr == "" || monthStr == "" {
		http.Error(w, "missing query element", http.StatusBadRequest)
		return
	}

	year, err := strconv.Atoi(yearStr)
	if err != nil {
		http.Error(w, "year is not an integer", http.StatusBadRequest)
		return
	}
	month, err := strconv.Atoi(monthStr)
	if err != nil {
		http.Error(w, "month is not an integer", http.StatusBadRequest)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	question, errQ := database.Get(year, month, "question")
	link, errL := database.Get(year, month, "link")
	if errQ != nil || errL != nil {
		// If not found, answer empty json
		w.Write([]byte("{}"))
		return
	}
	poll := Poll{Year: year, Month: month, Question: question.Content, Link: link.Content}
	json.NewEncoder(w).Encode(poll)
}

// AddPoll godoc
// @Summary Create a new poll
// @Description Create a new poll
// @Tags poll
// @Accept json
// @Produce  json
// @Success 201 {object} Poll
// @Param poll body Poll true "Poll to create"
// @Router /api/admin/poll [post]
func AddPoll(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	if r.Body == http.NoBody {
		http.Error(w, "request body is empty", http.StatusBadRequest)
		return
	}

	decoder := json.NewDecoder(r.Body)
	var poll Poll
	err := decoder.Decode(&poll)
	if err != nil {
		fmt.Println(err)
	}

	err = database.Create(poll.Year, poll.Month, "question", poll.Question)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	err = database.Create(poll.Year, poll.Month, "link", poll.Link)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusCreated)
	json.NewEncoder(w).Encode(poll)

	log.Printf("| new poll | %v", r.RemoteAddr)
}

// UpdatePoll godoc
// @Summary Update a specific poll' content
// @Description Update a specific poll' content
// @Tags poll
// @Accept json
// @Produce  json
// @Success 200 {object} Poll
// @Param poll body Poll true "Poll to update with new content"
// @Router /api/admin/poll [put]
func UpdatePoll(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	if r.Body == http.NoBody {
		http.Error(w, "request body is empty", http.StatusBadRequest)
		return
	}

	decoder := json.NewDecoder(r.Body)
	var poll Poll
	err := decoder.Decode(&poll)
	if err != nil {
		fmt.Println(err)
	}

	// Check if this monthly news exists
	_, errQ := database.Get(poll.Year, poll.Month, "question")
	_, errL := database.Get(poll.Year, poll.Month, "link")

	if errQ != nil || errL != nil {
		err = database.Create(poll.Year, poll.Month, "question", poll.Question)
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

		err = database.Create(poll.Year, poll.Month, "link", poll.Link)
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

		w.WriteHeader(http.StatusCreated)
		json.NewEncoder(w).Encode(poll)
		log.Printf("| new monthly news | year : %d month : %d | %v", poll.Year, poll.Month, r.RemoteAddr)
		return

	} else {
		err = database.Update(poll.Year, poll.Month, "question", poll.Question)
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

		err = database.Update(poll.Year, poll.Month, "link", poll.Link)
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}

		json.NewEncoder(w).Encode(poll)
		log.Printf("| updated poll year : %d month : %d | %v", poll.Year, poll.Month, r.RemoteAddr)
	}
}

// DeletePoll godoc
// @Summary Delete a specific poll
// @Description Delete a specific poll
// @Tags poll
// @Produce  json
// @Success 200 {string} string "successful delete"
// @Param year path int true "Year of the poll"
// @Param month path int true "Month of the poll"
// @Router /api/admin/poll/{year}/{month} [delete]
func DeletePoll(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	yearStr := vars["year"]
	monthStr := vars["month"]

	if yearStr == "" || monthStr == "" {
		http.Error(w, "missing query element", http.StatusBadRequest)
		return
	}

	year, err := strconv.Atoi(yearStr)
	if err != nil {
		http.Error(w, "year is not an integer", http.StatusBadRequest)
		return
	}
	month, err := strconv.Atoi(monthStr)
	if err != nil {
		http.Error(w, "month is not an integer", http.StatusBadRequest)
		return
	}

	err = database.Delete(year, month, "question")
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	err = database.Delete(year, month, "link")
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}

	w.WriteHeader(http.StatusOK)
	w.Write([]byte("successful delete"))
}