package controllers;

import play.data.Form;
import play.mvc.Controller;
import play.mvc.Result;
import play.libs.F.Function;
import play.libs.F.Function0;
import play.libs.F.Promise;

import controllers.Application.Login;
import models.User;
import views.html.home;
import views.html.login;

import static play.data.Form.form;



public class Auth extends Controller {

    public static Promise<Result> register() {
        final Form<RegistrationForm> registrationForm =
            form(RegistrationForm.class).bindFromRequest();
        if (registrationForm.hasErrors()) {
            Promise<Result> errorResult = Promise.promise(
                new Function0<Result>() {
                    public Result apply() {
                        return badRequest(home.render(registrationForm));
                }
            });
            return errorResult;
        }
        final User user = new User(registrationForm.get().email,
                                   registrationForm.get().password);
        if (user.exists().get()) {
            return Promise.promise(new Function0<Result>() {
                public Result apply() {
                    flash("error", "User already exists.");
                    return redirect(routes.Application.home());
                }});
        } else {
            Promise<User> newUser = user.create();
            return newUser.map(new Function<User, Result>() {
                public Result apply(User user) {
                    if (user == null) {
                        flash("error", "Registration failed.");
                    } else {
                        flash("success", "Registration successful.");
                    }
                    return redirect(routes.Application.home());
                }
            });
        }
    }

    public static Promise<Result> authenticate() {
        final Form<Login> loginForm = form(Login.class).bindFromRequest();
        if (loginForm.hasErrors()) {
            Promise<Result> errorResult = Promise.promise(
                new Function0<Result>() {
                    public Result apply() {
                        return badRequest(login.render(loginForm));
                    }
                }
            );
            return errorResult;
        }
        Promise<User> user = new User(loginForm.get().email,
                                      loginForm.get().password).get();
        return user.map(new Function<User, Result>() {
            public Result apply(User user) {
                if (user == null) {
                    flash("error", "Login failed: Unknown user.");
                    return badRequest(login.render(loginForm));
                } else {
                    session().clear();
                    session("email", loginForm.get().email);
                    flash("success", "Login successful.");
                    return redirect(routes.Application.home());
                }
            }
        });
    }

    public static class RegistrationForm extends Login {}

}

@@ -323,17 +323,16 @@
 form;%0A%0A%0A
-%0A
 public c
@@ -1003,28 +1003,31 @@
 d);%0A        
-if (
+return 
 user.exists(
@@ -1032,17 +1032,181 @@
 s().
-get()) %7B%0A
+flatMap(%0A            new Function%3CBoolean, Promise%3CResult%3E%3E() %7B%0A                public Promise%3CResult%3E apply(Boolean exists) %7B%0A                    if (exists) %7B%0A            
     
@@ -1270,32 +1270,44 @@
                 
+     
+       
 public Result ap
@@ -1306,32 +1306,44 @@
 esult apply() %7B%0A
+            
                 
@@ -1398,32 +1398,44 @@
                 
+           
+ 
 return redirect(
@@ -1482,21 +1482,65 @@
     
-%7D%7D);%0A
+            %7D%0A                        %7D);%0A       
         
 %7D el
@@ -1527,32 +1527,37 @@
 %0A               
+     
 %7D else %7B%0A       
@@ -1553,32 +1553,44 @@
 e %7B%0A            
+          
+  
 Promise%3CUser%3E ne
@@ -1608,24 +1608,36 @@
 r.create();%0A
+            
             
@@ -1694,32 +1694,44 @@
                 
+ 
+           
 public Result ap
@@ -1759,32 +1759,44 @@
                 
+    
+        
 if (user == null
@@ -1791,32 +1791,44 @@
 user == null) %7B%0A
+            
                 
@@ -1887,32 +1887,44 @@
                 
+          
+  
 %7D else %7B%0A       
@@ -1908,32 +1908,44 @@
        %7D else %7B%0A
+            
                 
@@ -1968,16 +1968,58 @@
 uccess%22,
+%0A                                         
  %22Regist
@@ -2052,34 +2052,58 @@
                 
+    
-%7D%0A
+        %7D%0A            
                 
@@ -2158,34 +2158,52 @@
                 
+          
-%7D%0A
+  %7D%0A      
             %7D);%0A
@@ -2202,21 +2202,73 @@
     
-%7D);%0A  
       %7D
+);%0A                    %7D%0A                %7D%0A            %7D);
 %0A   

Make `Auth` controller fully asynchronous.