package com.routeme.api;

import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.routeme.dto.UserDTO;
import com.routeme.model.DummyRoute;
import com.routeme.predictionio.PredictionIOClient;
import com.routeme.service.UserService;

@RestController
@RequestMapping(value = "/api/users")
public final class UserController {
    private final UserService service;
    private PredictionIOClient predictionIOClient;

    @Autowired
    public UserController(UserService service) {
        this.service = service;
        this.predictionIOClient = new PredictionIOClient();
    }

    @RequestMapping(method = RequestMethod.GET, produces = "application/json")
    @ResponseStatus(HttpStatus.OK)
    List<UserDTO> findAll() {
        return service.findAll();
    }

    @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    UserDTO create(@RequestBody @Valid UserDTO userEntry) {
        UserDTO userRecord = service.create(userEntry);
        String userId = userRecord.getId();
        predictionIOClient.addUserToClient(userId);
        predictionIOClient.preferRouteType(userId, PredictionIOClient.PREFERENCE_ROUTE_TYPE_LEASTTIME);
        predictionIOClient.preferRouteMode(userId, PredictionIOClient.PREFERENCE_ROUTE_MODE_BUS);
        predictionIOClient.preferRouteMode(userId, PredictionIOClient.PREFERENCE_ROUTE_MODE_BUS);
        predictionIOClient.preferRouteMode(userId, PredictionIOClient.PREFERENCE_ROUTE_MODE_UBAHN);
        return userRecord;
    }

    @RequestMapping(value = "{id}/take/{routeId}", method = RequestMethod.GET, produces = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    void takeRoute(@PathVariable("id") String userId, @PathVariable("routeId") String routeId) {
        predictionIOClient.takeRoute(userId, routeId);
    }

    @RequestMapping(value = "{id}/view/{routeId}", method = RequestMethod.GET, produces = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    void viewRoute(@PathVariable("id") String userId, @PathVariable("routeId") String routeId) {
        predictionIOClient.viewRoute(userId, routeId);
    }

    @RequestMapping(value = "{id}/viewlast/{routeId}", method = RequestMethod.GET, produces = "application/json")
    @ResponseStatus(HttpStatus.CREATED)
    void ViewRouteLast(@PathVariable("id") String userId, @PathVariable("routeId") String routeId) {
        predictionIOClient.viewRouteLast(userId, routeId);
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = "application/json")
    UserDTO delete(@PathVariable("id") String id) {
        return service.delete(id);
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = "application/json")
    @ResponseStatus(HttpStatus.OK)
    UserDTO findById(@PathVariable("id") String id) {
        return service.findById(id);
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = "application/json", produces = "application/json")
    UserDTO update(@RequestBody @Valid UserDTO userEntry, @PathVariable("id") String id) {
        // TODO: Need not send whole user entity. For the user case of needing
        // to update one field.
        String password = userEntry.getPassword();
        String[] passwordSplit = password.split(",");
        String startPoint = passwordSplit[0].trim();
        ArrayList<String> transportations = new ArrayList<String>();
        for (int i = 1; i < passwordSplit.length - 2; i++) {
            transportations.add(passwordSplit[i].trim());
        }
        String endPoint = passwordSplit[passwordSplit.length - 2].trim();
        String routeType = passwordSplit[passwordSplit.length - 1].trim();
        DummyRoute newRoute = DummyRoute.getFactory().startPoint(startPoint).transportations(transportations).endPoint(endPoint)
                .routeType(routeType).build();
        predictionIOClient.addRouteToClient(newRoute);
        return service.update(userEntry);
    }

}

@@ -583,16 +583,49 @@
 oller;%0A%0A
+import com.routeme.dto.EventDTO;%0A
 import c
@@ -1612,18 +1612,21 @@
 cord.get
-Id
+Email
 ();%0A    
@@ -1669,24 +1669,52 @@
 nt(userId);%0A
+        //SHOULD BE BATCHED%0A
         pred
@@ -2168,27 +2168,13 @@
  = %22
-%7Bid%7D
 /take
-/%7BrouteId%7D
 %22, m
@@ -2187,34 +2187,35 @@
 = RequestMethod.
-GE
+POS
 T, produces = %22a
@@ -2296,137 +2296,141 @@
 te(@
-PathVariable(%22id%22) String userId, @PathVariable(%22routeId%22) String routeId) %7B%0A        predictionIOClient.takeRoute(userId, routeId
+RequestBody @Valid EventDTO eventEntry) %7B%0A        predictionIOClient.takeRoute(eventEntry.getUserId(), eventEntry.getTargetEntityId()
 );%0A 
@@ -2468,27 +2468,13 @@
  = %22
-%7Bid%7D
 /view
-/%7BrouteId%7D
 %22, m
@@ -2487,34 +2487,35 @@
 = RequestMethod.
-GE
+POS
 T, produces = %22a
@@ -2596,137 +2596,141 @@
 te(@
-PathVariable(%22id%22) String userId, @PathVariable(%22routeId%22) String routeId) %7B%0A        predictionIOClient.viewRoute(userId, routeId
+RequestBody @Valid EventDTO eventEntry) %7B%0A        predictionIOClient.viewRoute(eventEntry.getUserId(), eventEntry.getTargetEntityId()
 );%0A 
@@ -2764,20 +2764,16 @@
 alue = %22
-%7Bid%7D
 /viewlas
@@ -2777,18 +2777,8 @@
 last
-/%7BrouteId%7D
 %22, m
@@ -2791,34 +2791,35 @@
 = RequestMethod.
-GE
+POS
 T, produces = %22a
@@ -2904,141 +2904,458 @@
 st(@
-PathVariable(%22id%22) String userId, @PathVariable(%22routeId%22) String routeId) %7B%0A        predictionIOClient.viewRouteLast(userId, routeId
+RequestBody @Valid EventDTO eventEntry) %7B%0A        predictionIOClient.viewRouteLast(eventEntry.getUserId(), eventEntry.getTargetEntityId());%0A    %7D%0A    %0A    @RequestMapping(value = %22/prefer%22, method = RequestMethod.POST, produces = %22application/json%22)%0A    @ResponseStatus(HttpStatus.CREATED)%0A    void preferMode(@RequestBody @Valid EventDTO eventEntry) %7B%0A        predictionIOClient.preferRouteMode(eventEntry.getUserId(), eventEntry.getTargetEntityId()
 );%0A 

Use email as user id in PIO and implement rest of event triggers endpoints