package server
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"github.com/gorilla/mux"
"github.com/iwasforcedtobehere/gomeme/internal/meme"
)
// Server represents our meme server
type Server struct {
generator *meme.Generator
}
// New creates a new server instance
func New() *Server {
return &Server{
generator: meme.NewGenerator(),
}
}
// Routes sets up all the HTTP routes
func (s *Server) Routes() http.Handler {
r := mux.NewRouter()
// Static files
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("web/static/"))))
// Web interface
r.HandleFunc("/", s.homeHandler).Methods("GET")
r.HandleFunc("/generate", s.generateWebHandler).Methods("POST")
// API endpoints
api := r.PathPrefix("/api/v1").Subrouter()
api.HandleFunc("/memes", s.generateAPIHandler).Methods("POST")
api.HandleFunc("/memes/{id}", s.getMemeHandler).Methods("GET")
api.HandleFunc("/templates", s.getTemplatesHandler).Methods("GET")
api.HandleFunc("/health", s.healthHandler).Methods("GET")
return r
}
// homeHandler serves the main page
func (s *Server) homeHandler(w http.ResponseWriter, r *http.Request) {
html := `
GoMeme - Because Manual Meme Making is for Peasants
🎠GoMeme Generator
Automated meme production because who has time for manual labor?
`
w.Header().Set("Content-Type", "text/html")
fmt.Fprint(w, html)
}
// generateWebHandler handles web form submissions
func (s *Server) generateWebHandler(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
http.Error(w, "Failed to parse form", http.StatusBadRequest)
return
}
req := meme.GenerateRequest{
Template: r.FormValue("template"),
TopText: r.FormValue("top_text"),
BottomText: r.FormValue("bottom_text"),
}
result, err := s.generator.Generate(req)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to generate meme: %v", err), http.StatusInternalServerError)
return
}
// Return HTML with the generated meme
html := fmt.Sprintf(`
Your Meme is Ready!
🎉 Your Meme is Ready!
Share URL: %s
`, result.Filename, result.Filename, result.ShareURL)
w.Header().Set("Content-Type", "text/html")
fmt.Fprint(w, html)
}
// generateAPIHandler handles API meme generation requests
func (s *Server) generateAPIHandler(w http.ResponseWriter, r *http.Request) {
var req meme.GenerateRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
result, err := s.generator.Generate(req)
if err != nil {
http.Error(w, fmt.Sprintf("Failed to generate meme: %v", err), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(result)
}
// getMemeHandler retrieves a specific meme by ID
func (s *Server) getMemeHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
// Convert string ID to int for demo purposes
memeID, err := strconv.Atoi(id)
if err != nil {
http.Error(w, "Invalid meme ID", http.StatusBadRequest)
return
}
meme, err := s.generator.GetMeme(memeID)
if err != nil {
http.Error(w, "Meme not found", http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(meme)
}
// getTemplatesHandler returns available meme templates
func (s *Server) getTemplatesHandler(w http.ResponseWriter, r *http.Request) {
templates := s.generator.GetTemplates()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
"templates": templates,
"count": len(templates),
})
}
// healthHandler provides health check endpoint
func (s *Server) healthHandler(w http.ResponseWriter, r *http.Request) {
response := map[string]interface{}{
"status": "healthy",
"message": "GoMeme is alive and ready to generate some fucking awesome memes!",
"timestamp": "2025-09-12T00:00:00Z",
"version": "1.0.0",
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}