package handler import ( "encoding/json" "errors" "net/http" "strings" "5803025020/w04/internal/middleware" "5803025020/w04/internal/models" "5803025020/w04/internal/store" "github.com/google/uuid" "github.com/jackc/pgx/v5" ) type SnippetHandler struct { snippetStore *store.SnippetStore } func NewSnippetHandler(snippetStore *store.SnippetStore) *SnippetHandler { return &SnippetHandler{snippetStore: snippetStore} } type snippetRequest struct { Title string `json:"title"` Content string `json:"content"` } func (h *SnippetHandler) Snippets(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: h.List(w, r) case http.MethodPost: h.Create(w, r) default: http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) } } func (h *SnippetHandler) SnippetByID(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: h.Get(w, r) case http.MethodDelete: h.Delete(w, r) default: http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) } } func (h *SnippetHandler) Create(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) return } userID := middleware.GetUserID(r.Context()) if userID == "" { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } var req snippetRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Bad Request", http.StatusBadRequest) return } req.Title = strings.TrimSpace(req.Title) req.Content = strings.TrimSpace(req.Content) if req.Title == "" || req.Content == "" { http.Error(w, "Title and content are required", http.StatusBadRequest) return } snippet := &models.Snippet{ ID: uuid.New().String(), Title: req.Title, Content: req.Content, UserID: userID, } if err := h.snippetStore.Create(r.Context(), snippet); err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) _ = json.NewEncoder(w).Encode(snippet) } func (h *SnippetHandler) List(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) return } snippets, err := h.snippetStore.GetAll(r.Context()) if err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode(snippets) } func (h *SnippetHandler) Get(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) return } id := r.PathValue("id") if id == "" { path := strings.TrimPrefix(r.URL.Path, "/snippets/") id = strings.TrimSuffix(path, "/") } if id == "" { http.Error(w, "Bad Request", http.StatusBadRequest) return } snippet, err := h.snippetStore.GetByID(r.Context(), id) if err != nil { if errors.Is(err, pgx.ErrNoRows) { http.Error(w, "Snippet not found", http.StatusNotFound) return } http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode(snippet) } func (h *SnippetHandler) Delete(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodDelete { http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) return } id := r.PathValue("id") if id == "" { path := strings.TrimPrefix(r.URL.Path, "/snippets/") id = strings.TrimSuffix(path, "/") } if id == "" { http.Error(w, "Bad Request", http.StatusBadRequest) return } if err := h.snippetStore.Delete(r.Context(), id); err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } w.WriteHeader(http.StatusNoContent) }