package io.pathfinder.controllers;

import com.avaje.ebean.Ebean;
import com.avaje.ebean.text.json.JsonContext;
import com.fasterxml.jackson.databind.JsonNode;
import play.mvc.*;
import io.pathfinder.models.Commodity;

import java.util.Iterator;
import java.util.List;

/**
 * Created by Carter on 9/17/2015.
 */
public class CommodityController extends Controller {

  private JsonContext jsonContext = Ebean.createJsonContext();

  public Result getCommodities() {
    return ok(jsonContext.toJson(Commodity.find.all()));
  }

  public Result getCommodity(long id) {
    Commodity commodity = Commodity.find.byId(id);

    if (commodity == null) {
      return notFound();
    }

    return ok(jsonContext.toJson(commodity));
  }

  public Result createCommodity() {
    JsonNode json = request().body().asJson();
    if (json == null) {
      return badRequest("Expecting content-type text/json or application/json");
    }

    Commodity commodity = new Commodity();

    commodity.startLatitude = json.findPath("startLatitude").asDouble();
    commodity.startLongitude = json.findPath("startLongitude").asDouble();
    commodity.endLatitude = json.findPath("endLatitude").asDouble();
    commodity.endLongitude = json.findPath("endLongitude").asDouble();
    commodity.param = json.findPath("param").asInt();

    commodity.save();

    return created(jsonContext.toJson(commodity));
  }

  public Result editCommodity(long id) {
    Commodity commodity = Commodity.find.byId(id);

    if (commodity == null) {
      return notFound();
    }

    JsonNode json = request().body().asJson();

    if (json.hasNonNull("startLatitude")) {
      commodity.startLatitude = json.findPath("startLatitude").asDouble();
    }
    if (json.hasNonNull("startLongitude")) {
      commodity.startLongitude = json.findPath("startLongitude").asDouble();
    }
    if (json.hasNonNull("endLatitude")) {
      commodity.endLatitude = json.findPath("endLatitude").asDouble();
    }
    if (json.hasNonNull("endLongitude")) {
      commodity.endLongitude = json.findPath("endLongitude").asDouble();
    }
    if (json.hasNonNull("param")) {
      commodity.param = json.findPath("param").asInt();
    }

    commodity.update();

    return ok();
  }

  public Result deleteCommodity(long id) {
    Commodity commodity = Commodity.find.byId(id);

    if (commodity == null) {
      return notFound();
    }

    commodity.delete();
    return ok(jsonContext.toJson(commodity));
  }

}

@@ -153,16 +153,105 @@
 onNode;%0A
+import com.fasterxml.jackson.databind.node.ObjectNode;%0Aimport play.api.libs.json.JsPath;%0A
 import p
@@ -332,29 +332,39 @@
 or;%0A
+%0A
 import 
-java.util.List
+static play.libs.Json.*
 ;%0A%0A/
@@ -1047,372 +1047,205 @@
 dity
- = new Commodity();%0A%0A    commodity.startLatitude = json.findPath(%22startLatitude%22).asDouble();%0A    commodity.startLongitude = json.findPath(%22startLongitude%22).asDouble();%0A    commodity.endLatitude = json.findPath(%22endLatitude%22).asDouble();%0A    commodity.endLongitude = json.findPath(%22endLongitude%22).asDoubl
+;%0A%0A    try %7B%0A      commodity = fromJson(json, Commodity.class);%0A    %7D catch (Exception e) %7B%0A      return badRequest(%22Unable to map json to commodity object: %22 + e.getMessag
 e()
+)
 ;%0A    
-commodity.param = json.findPath(%22param%22).asInt();%0A%0A
+%7D%0A%0A    try %7B%0A  
     
@@ -1259,24 +1259,26 @@
 ty.save();%0A%0A
+  
     return c
@@ -1308,32 +1308,161 @@
 on(commodity));%0A
+    %7D catch (Exception e) %7B%0A      return internalServerError(%22Error saving commodity to the database: %22 + e.getMessage());%0A    %7D%0A
   %7D%0A%0A  public Re
@@ -1604,39 +1604,140 @@
 %0A    %7D%0A%0A    
-JsonNode json =
+ObjectNode commodityJson = (ObjectNode) toJson(commodity);%0A    ObjectNode body;%0A%0A    try %7B%0A      body = (ObjectNode)
  request().b
@@ -1756,134 +1756,137 @@
 ();%0A
-%0A    if (json.hasNonNull(%22startLatitude%22)) %7B%0A      commodity.startLatitude = json.findPath(%22startLatitude%22).asDoubl
+    %7D catch (ClassCastException e) %7B%0A      return badRequest(%22Cannot cast request body to ObjectNode: %22 + e.getMessag
 e()
+)
 ;%0A    %7D%0A
     
@@ -1885,298 +1885,215 @@
   %7D%0A
+%0A
     
-if (json.hasNonNull(%22startLongitude%22)) %7B%0A      commodity.startLongitude = json.findPath(%22startLongitude%22).asDouble();%0A    %7D%0A    if (json.hasNonNull(%22endLatitude%22)) %7B%0A      commodity.endLatitude = json.findPath(%22endLatitude%22).asDouble();%0A    %7D%0A    if (json.hasNonNull(%22endLongitude%22
+Iterator%3CString%3E fields = commodityJson.fieldNames();%0A    while (fields.hasNext()) %7B%0A      String field = fields.next();%0A%0A      if (field.equals(%22id%22))%0A        continue;%0A%0A      if (body.has(field
 )) %7B%0A
+  
     
@@ -2107,66 +2107,53 @@
 dity
-.endLongitude = json.findPath(%22endLongitude%22).asDouble(
+Json.replace(field, body.findPath(field)
 );%0A
+  
     
@@ -2162,103 +2162,83 @@
     
-if (json.hasNonNull(%22param%22)) %7B%0A      commodity.param = json.findPath(%22param%22).asInt();%0A    %7D%0A%0A
+%7D%0A%0A    try %7B%0A      commodity = fromJson(commodityJson, Commodity.class);%0A  
     
@@ -2258,24 +2258,26 @@
 ate();%0A%0A    
+  
 return ok();
@@ -2277,16 +2277,124 @@
 n ok();%0A
+    %7D catch (Exception e) %7B%0A      return badRequest(%22Unable to update commodity: %22 + e.getMessage());%0A    %7D%0A
   %7D%0A%0A  p

Refactor create/edit commodity