package org.sagebionetworks.bridge.validators;

import static org.sagebionetworks.bridge.validators.SignInValidator.RequiredFields.STUDY;
import static org.sagebionetworks.bridge.validators.SignInValidator.RequiredFields.EMAIL;
import static org.sagebionetworks.bridge.validators.SignInValidator.RequiredFields.PASSWORD;
import static org.sagebionetworks.bridge.validators.SignInValidator.RequiredFields.PHONE;
import static org.sagebionetworks.bridge.validators.SignInValidator.RequiredFields.TOKEN;
import static org.sagebionetworks.bridge.validators.SignInValidator.RequiredFields.REAUTH;

import static org.apache.commons.lang3.StringUtils.isBlank;

import java.util.Set;

import org.sagebionetworks.bridge.models.accounts.SignIn;

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import com.google.common.collect.Sets;

public class SignInValidator implements Validator {
    
    /** Request to sign in via email. */
    public static final SignInValidator EMAIL_SIGNIN_REQUEST = new SignInValidator(STUDY, EMAIL);
    /** Sign in using token sent through email. */    
    public static final SignInValidator EMAIL_SIGNIN = new SignInValidator(STUDY, EMAIL, TOKEN);

    /** Request to sign in via phone. */
    public static final SignInValidator PHONE_SIGNIN_REQUEST = new SignInValidator(STUDY, PHONE);
    /** Sign in using token sent through SMS. */
    public static final SignInValidator PHONE_SIGNIN = new SignInValidator(STUDY, PHONE, TOKEN);

    /** Sign in using an email and password. */
    public static final SignInValidator PASSWORD_SIGNIN = new SignInValidator(STUDY, EMAIL, PASSWORD);
    /** Reauthentication. */
    public static final SignInValidator REAUTH_SIGNIN = new SignInValidator(STUDY, EMAIL, REAUTH);
    
    static enum RequiredFields {
        STUDY,
        EMAIL,
        PASSWORD,
        PHONE,
        TOKEN,
        REAUTH
    }
    
    private Set<RequiredFields> requiredFields;

    private SignInValidator(RequiredFields... fields) {
        requiredFields = Sets.newHashSet(fields);
    }
    
    @Override
    public boolean supports(Class<?> clazz) {
        return SignIn.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object object, Errors errors) {
        SignIn signIn = (SignIn)object;
        
        if (requiredFields.contains(STUDY) && isBlank(signIn.getStudyId())) {
            errors.rejectValue("study", "is required");
        }
        if (requiredFields.contains(EMAIL) && isBlank(signIn.getEmail())) {
            errors.rejectValue("email", "is required");
        }
        if (requiredFields.contains(PASSWORD) && isBlank(signIn.getPassword())) {
            errors.rejectValue("password", "is required");
        }
        if (requiredFields.contains(PHONE) && isBlank(signIn.getPhone())) {
            errors.rejectValue("phone", "is required");
        }
        if (requiredFields.contains(TOKEN) && isBlank(signIn.getToken())) {
            errors.rejectValue("token", "is required");
        }
        if (requiredFields.contains(REAUTH) && isBlank(signIn.getReauthToken())) {
            errors.rejectValue("reauthToken", "is required");
        }
    }

}

@@ -647,16 +647,67 @@
 Blank;%0A%0A
+import java.util.Arrays;%0Aimport java.util.EnumSet;%0A
 import j
@@ -1089,32 +1089,43 @@
 SignInValidator(
+EnumSet.of(
 STUDY, EMAIL);%0A 
@@ -1121,16 +1121,17 @@
 , EMAIL)
+)
 ;%0A    /*
@@ -1246,32 +1246,43 @@
 SignInValidator(
+EnumSet.of(
 STUDY, EMAIL, TO
@@ -1277,32 +1277,33 @@
 Y, EMAIL, TOKEN)
+)
 ;%0A%0A    /** Reque
@@ -1405,32 +1405,43 @@
 SignInValidator(
+EnumSet.of(
 STUDY, PHONE);%0A 
@@ -1437,16 +1437,17 @@
 , PHONE)
+)
 ;%0A    /*
@@ -1560,24 +1560,35 @@
 InValidator(
+EnumSet.of(
 STUDY, PHONE
@@ -1595,16 +1595,17 @@
 , TOKEN)
+)
 ;%0A%0A    /
@@ -1717,32 +1717,43 @@
 SignInValidator(
+EnumSet.of(
 STUDY, EMAIL, PA
@@ -1759,16 +1759,17 @@
 ASSWORD)
+)
 ;%0A    /*
@@ -1867,16 +1867,27 @@
 lidator(
+EnumSet.of(
 STUDY, E
@@ -1899,16 +1899,17 @@
  REAUTH)
+)
 ;%0A    %0A 
@@ -2056,16 +2056,20 @@
 private 
+Enum
 Set%3CRequ
@@ -2125,16 +2125,24 @@
 lidator(
+EnumSet%3C
 Required
@@ -2151,11 +2151,9 @@
 elds
-...
+%3E
  fie
@@ -2188,31 +2188,14 @@
 s = 
-Sets.newHashSet(
 fields
-)
 ;%0A  

Create set as an EnumSet without an intermediate Set object.