/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package foam.nanos.auth;

import foam.core.FObject;
import foam.core.X;
import foam.dao.DAO;
import foam.dao.ProxyDAO;
import foam.dao.Sink;
import foam.mlang.MLang;
import foam.mlang.sink.Count;
import java.security.NoSuchAlgorithmException;

//TODO: Throw exception for print statements when they are ready
public class AuthenticatedUserDAO
  extends ProxyDAO
{

  public AuthenticatedUserDAO(DAO delegate) {
    setDelegate(delegate);
  }

  @Override
  public FObject put_(X x, FObject fObject) {
    User user = (User) fObject;

    if ( getDelegate().find_(x, user.getId()) != null ) {
      System.out.println("A user has already been registered with this account");
      return null;
    }

    AuthService service = (AuthService) x.get("auth");
    if ( service == null ) {
      System.out.println("Auth Service not started");
      return null;
    }

    try {
      service.validateUser(user);
      Count count = (Count) this.limit(1).where(MLang.EQ(User.EMAIL, user.getEmail())).select(new Count());

      if ( count.getValue() > 0 ) {
        System.out.println("An account is already registered with this email address");
        return null;
      }

      String salt = UserAndGroupAuthService.generateRandomSalt();
      user.setPassword(UserAndGroupAuthService.hashPassword(user.getPassword(), salt) + ":" + salt);

      return getDelegate().put_(x, user);
    }
    catch (RuntimeException e) {
      e.printStackTrace();
      return null;
    }
    catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
      return null;
    }
  }

  @Override
  /**
   * Restrict find method to only return the logged in user object
   * */
  public FObject find_(X x, Object id) {
    User user = (User) x.get("user");

    if ( user == null || user.getId() != (long) id ) {
      System.out.println("User is not logged in");
      return null;
    }

    return super.find_(x, user.getId());
  }

  @Override
  public Sink select(Sink sink) {
    return null;
  }

  @Override
  public FObject remove(FObject obj) {
    return null;
  }

  @Override
  public void removeAll() {
    return;
  }
}

@@ -365,73 +365,8 @@
 n;%0A%0A
-//TODO: Throw exception for print statements when they are ready%0A
 publ
@@ -416,17 +416,16 @@
 xyDAO%0A%7B%0A
-%0A
   public
@@ -549,16 +549,40 @@
 fObject)
+ throws RuntimeException
  %7B%0A    U
@@ -673,33 +673,41 @@
 %7B%0A      
-System.out.printl
+throw new RuntimeExceptio
 n(%22A use
@@ -757,35 +757,16 @@
 ount%22);%0A
-      return null;%0A
     %7D%0A%0A 
@@ -854,33 +854,41 @@
 %7B%0A      
-System.out.printl
+throw new RuntimeExceptio
 n(%22Auth 
@@ -910,35 +910,16 @@
 rted%22);%0A
-      return null;%0A
     %7D%0A%0A 
@@ -1114,33 +1114,41 @@
         
-System.out.printl
+throw new RuntimeExceptio
 n(%22An ac
@@ -1206,29 +1206,8 @@
 %22);%0A
-        return null;%0A
     
@@ -1470,46 +1470,15 @@
     
-e.printStackTrace();%0A      return null
+throw e
 ;%0A  
@@ -1710,16 +1710,40 @@
 ject id)
+ throws RuntimeException
  %7B%0A    U
@@ -1841,25 +1841,33 @@
     
-System.out.printl
+throw new RuntimeExceptio
 n(%22U
@@ -1890,35 +1890,16 @@
 d in%22);%0A
-      return null;%0A
     %7D%0A%0A 
@@ -1991,155 +1991,424 @@
 nk) 
-%7B%0A    return null;%0A  %7D%0A%0A  @Override%0A  public FObject remove(FObject obj) %7B%0A    return null;%0A  %7D%0A%0A  @Override%0A  public void removeAll() %7B%0A    return
+throws RuntimeException %7B%0A    throw new RuntimeException(%22Select not allowed on Authenticated User DAO%22);%0A  %7D%0A%0A  @Override%0A  public FObject remove(FObject obj) throws RuntimeException %7B%0A    throw new RuntimeException(%22Remove not allowed on Authenticated User DAO%22);%0A  %7D%0A%0A  @Override%0A  public void removeAll() throws RuntimeException %7B%0A    throw new RuntimeException(%22RemoveAll not allowed on Authenticated User DAO%22)
 ;%0A  

Throw exceptions on Authenticated UserDAO