package com.skogsrud.halvard.sparkjava.spike;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static spark.Spark.*;

/**
 * Adapted from https://github.com/perwendel/spark
 */
public class Books {
    private static Map<String, Book> books = new HashMap<>();
    private final ObjectMapper objectMapper;

    public Books(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    public void run() throws Exception {
        // Creates a new book resource, will return the ID to the created resource
        // author and title are sent as JSON, e.g., { "author": "Foo", "title": "Bar" }
        post("/books", "application/json", (request, response) -> {
            Book book = objectMapper.readValue(request.body(), Book.class);
            String id = UUID.randomUUID().toString();
            books.put(id, book);
            response.status(201);
            return id;
        });

        // Gets the book resource for the provided id
        get("/books/:id", (request, response) -> {
            String id = request.params(":id");
            Book book = books.get(id);
            if (book == null) {
                response.status(404);
                return "Book with id [" + id + "] not found";
            }
            response.type("application/json");
            return book;
        }, objectMapper::writeValueAsString);

        // Updates the book resource for the provided id with new information
        // author and title are sent as query parameters e.g. /books/<id>?author=Foo&title=Bar
        put("/books/:id", (request, response) -> {
            String id = request.params(":id");
            Book book = new Book(request.queryParams("author"), request.queryParams("title"));
            if (books.get(id) != null) {
                books.put(id, book);
                return book;
            } else {
                response.status(404);
                return "Book with id [" + id + "] not found";
            }
        });

        // Deletes the book resource for the provided id
        delete("/books/:id", (request, response) -> {
            String id = request.params(":id");
            Book book = books.remove(id);
            if (book == null) {
                response.status(404);
                return "Book with id [" + id + "] not found";
            }
            return "Book with id [" + id + "] deleted";
        });

        // Gets all books
        get("/books", (request, response) -> {
            response.type("application/json");
            return books;
        }, objectMapper::writeValueAsString);
    }

    /**
     * Use this main() method to run a server with only the routes defined in this class
     */
    public static void main(String[] args) throws Exception {
        new Books(new ObjectMapper()).run();
    }
}

@@ -92,16 +92,66 @@
 Mapper;%0A
+import spark.Request;%0A%0Aimport java.io.IOException;
 %0Aimport 
@@ -249,67 +249,8 @@
 *;%0A%0A
-/**%0A * Adapted from https://github.com/perwendel/spark%0A */%0A
 publ
@@ -570,13 +570,13 @@
 the 
-ID to
+id of
  the
@@ -592,16 +592,17 @@
 resource
+.
 %0A       
@@ -618,32 +618,60 @@
 r and title 
-are sent
+should be sent either:%0A        // 1.
  as JSON, e.
@@ -709,16 +709,21 @@
  %22Bar%22 %7D
+ ; or
 %0A       
@@ -727,40 +727,105 @@
     
-post(%22/books%22, %22application/json
+// 2. as form-encoded values in the request body, e.g., author=Foo&title=Bar%0A        post(%22/books
 %22, (
@@ -876,57 +876,39 @@
 k = 
-objectMapper.readValue(r
+readBookFromR
 equest
-.b
+B
 ody(
-), Book.class
+request
 );%0A 
@@ -1625,18 +1625,24 @@
 d title 
-ar
+should b
 e sent a
@@ -1647,62 +1647,35 @@
  as 
-query parameters e.g. /books/%3Cid%3E?author=Foo&title=Bar
+per the create 'post' route
 %0A   
@@ -1797,76 +1797,39 @@
 k = 
-new Book(request.queryParams(%22author%22), request.queryParams(%22title%22)
+readBookFromRequestBody(request
 );%0A 
@@ -2692,24 +2692,630 @@
 ng);%0A    %7D%0A%0A
+    private Book readBookFromRequestBody(Request request) throws IOException %7B%0A        Book book = null;%0A        switch (request.contentType()) %7B%0A            case %22application/json%22:%0A                book = objectMapper.readValue(request.body(), Book.class);%0A                break;%0A            case %22application/x-www-form-urlencoded%22:%0A                book = new Book(request.queryParams(%22author%22), request.queryParams(%22title%22));%0A                break;%0A            default:%0A                halt(400, %22Unsupported request content-type %5B%22 + request.contentType() + %22%5D%22);%0A        %7D%0A        return book;%0A    %7D%0A%0A
     /**%0A    

Allow request bodies either as JSON or form encoded