package services;

import fj.data.Either;
import fj.data.Option;
import org.sql2o.Connection;
import org.sql2o.Sql2oException;

import java.util.Date;
import java.util.List;

public class ExerciseService {
  public static class Exercise {
    public int id;
    public String description;
    public String type;
    public Integer creator;
    public Date createdAt;

    public Exercise(String description, String type, Integer creator, Date createdAt) {
      this.description = description;
      this.type = type;
      this.creator = creator;
      this.createdAt = createdAt;
    }
  }

  public static Either<Sql2oException, List<Exercise>> getExercises() {
    String sql = "SELECT * FROM exercise";

    try(Connection con = DatabaseService.getConnection()) {
      List<Exercise> exercises = con
        .createQuery(sql)
        .addColumnMapping("created_at", "createdAt")
        .executeAndFetch(Exercise.class);
      return Either.right(exercises);
    } catch (Sql2oException err) {
      return Either.left(err);
    }
  }

  public static Either<Sql2oException, Option<Exercise>> getExerciseById(int id) {
    String sql = "SELECT * FROM exercise where id = :id";

    try(Connection con = DatabaseService.getConnection()) {
      List<Exercise> exercises = con
        .createQuery(sql)
        .addParameter("id", id)
        .addColumnMapping("created_at", "createdAt")
        .executeAndFetch(Exercise.class);

      if(exercises.size() == 0) {
        return Either.right(Option.none());
      }
      return Either.right(Option.some(exercises.get(0)));
    } catch (Sql2oException err) {
      return Either.left(err);
    }
  }

  public static Either<Sql2oException, Option<Exercise>> createExercise(Exercise exercise) {
    String sql = "INSERT INTO exercise (description, type, creator, created_at) " +
                 "values (:description, :type, :creator, :createdAt)";

    int insertedId;

    try(Connection con = DatabaseService.getConnection()) {
        insertedId = con
          .createQuery(sql, true)
          .bind(exercise)
          .executeUpdate()
          .getKey(int.class);

    } catch (Sql2oException err) {
      return Either.left(err);
    }

    return getExerciseById(insertedId);
  }
}


@@ -12,16 +12,31 @@
 vices;%0A%0A
+import fj.Try;%0A
 import f
@@ -84,28 +84,24 @@
 ort 
-org.sql2o.Connection
+fj.function.Try0
 ;%0Aim
@@ -115,26 +115,22 @@
 g.sql2o.
-Sql2oExcep
+Connec
 tion;%0A%0Ai
@@ -609,37 +609,32 @@
 c static Either%3C
-Sql2o
 Exception, List%3C
@@ -701,24 +701,74 @@
 exercise%22;%0A%0A
+    Try0%3CList%3CExercise%3E, Exception%3E t = () -%3E %7B%0A  
     try(Conn
@@ -813,32 +813,34 @@
 tion()) %7B%0A      
+  
 List%3CExercise%3E e
@@ -854,32 +854,34 @@
 s = con%0A        
+  
 .createQuery(sql
@@ -882,32 +882,34 @@
 ry(sql)%0A        
+  
 .addColumnMappin
@@ -937,32 +937,34 @@
 tedAt%22)%0A        
+  
 .executeAndFetch
@@ -987,36 +987,25 @@
 ;%0A      
+  
 return 
-Either.right(
 exercise
@@ -1009,83 +1009,62 @@
 ises
-)
 ;%0A    
-%7D catch (Sql2oException err) %7B%0A      return Either.left(err
+  %7D%0A    %7D;%0A%0A    return Try.f(t).f().toEither(
 );%0A
-    %7D%0A
   %7D%0A
@@ -1079,37 +1079,32 @@
 c static Either%3C
-Sql2o
 Exception, Optio
@@ -1197,24 +1197,77 @@
 id = :id%22;%0A%0A
+    Try0%3COption%3CExercise%3E, Exception%3E t = () -%3E %7B%0A%0A  
     try(Conn
@@ -1316,24 +1316,26 @@
 ()) %7B%0A      
+  
 List%3CExercis
@@ -1345,32 +1345,34 @@
 exercises = con%0A
+  
         .createQ
@@ -1385,24 +1385,26 @@
 ql)%0A        
+  
 .addParamete
@@ -1415,16 +1415,18 @@
 d%22, id)%0A
+  
         
@@ -1470,32 +1470,34 @@
 tedAt%22)%0A        
+  
 .executeAndFetch
@@ -1521,16 +1521,18 @@
 %0A%0A      
+  
 if(exerc
@@ -1547,24 +1547,26 @@
 e() == 0) %7B%0A
+  
         retu
@@ -1564,37 +1564,24 @@
      return 
-Either.right(
 Option.none(
@@ -1581,25 +1581,24 @@
 n.none()
-)
 ;%0A      
 %7D%0A      
@@ -1585,26 +1585,31 @@
 ne();%0A      
+  
 %7D%0A
+%0A  
       return
@@ -1613,21 +1613,8 @@
 urn 
-Either.right(
 Opti
@@ -1642,82 +1642,62 @@
 (0))
-)
 ;%0A    
-%7D catch (Sql2oException err) %7B%0A      return Either.left(err);%0A    %7D
+  %7D%0A%0A    %7D;%0A%0A    return Try.f(t).f().toEither();
 %0A  %7D
@@ -1721,21 +1721,16 @@
  Either%3C
-Sql2o
 Exceptio
@@ -1723,32 +1723,33 @@
 ither%3CException,
+ 
  Option%3CExercise
@@ -1951,25 +1951,47 @@
     
-int insertedId;%0A%0A
+Try0%3CInteger, Exception%3E t = () -%3E %7B%0A  
     
@@ -2058,20 +2058,14 @@
     
-insertedId =
+return
  con
@@ -2186,93 +2186,96 @@
 s);%0A
-%0A
+  
     %7D
- catch (Sql2oException err) %7B%0A      return Either.left(err);%0A    %7D%0A%0A    return 
+%0A    %7D;%0A%0A    return Try.f(t).f().toEither()%0A      .right().bind(ExerciseService::
 getE
@@ -2289,19 +2289,8 @@
 ById
-(insertedId
 );%0A 

use Try to wrap possibly exception causing blocks and turn those into Eithers