package mil.nga.mapcache.auth;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.util.Log;

import java.net.URL;

/**
 * Logs the user into a specified server.
 */
public class UserLoggerInner {

    /**
     *
     */
    private static String MAPCACHE_ACCOUNT_TYPE = "mil.nga.mapcache";

    /**
     * The applications activity.
     */
    private Activity activity;

    /**
     * Contains what the user entered for their username and password if we needed to prompt them.
     */
    private UserPassModel model;

    /**
     * Constructor.
     *
     * @param activity The applications activity.
     */
    public UserLoggerInner(Activity activity) {
        this.activity = activity;
    }

    /**
     * Retrieves the user's username and password for the specified server.  If found a stored one
     * it will then use the specified authenticator to log the user into the server.  If a username
     * and password is not found in the AccountManager or if authentication fails, we will then
     * prompt the user for a username and password authenticate and then store it for later use.
     *
     * @param url
     * @param IAuthenticator
     */
    public void login(URL url, Authenticator IAuthenticator) {
        String host = url.getHost();
        AccountManager accountManager = AccountManager.get(this.activity);
        Account[] accounts = accountManager.getAccountsByType(MAPCACHE_ACCOUNT_TYPE);

        boolean authenticated = false;
        if (accounts != null && accounts.length > 0) {
            Account account = accounts[0];
            String userName = account.name;
            String password = accountManager.getPassword(account);
            authenticated = IAuthenticator.authenticate(url, userName, password);
        }

        while (!authenticated) {
            askUserAndWait(host);
            String username = model.getUsername();
            String password = model.getPassword();
            if (username != null && password != null) {
                authenticated = IAuthenticator.authenticate(url, username, password);
                if (authenticated) {
                    Account newAccount = new Account(username, MAPCACHE_ACCOUNT_TYPE);
                    accountManager.addAccountExplicitly(newAccount, password, null);
                }
            } else {
                // Not really authenticated, user cancelled the login
                authenticated = true;
            }
        }
    }

    /**
     * Prompts the user for their username and password, on the UI thread, and waits for the users
     * response before returning.
     *
     * @param host The server the user will be logging into.
     */
    private synchronized void askUserAndWait(String host) {
        activity.runOnUiThread(() -> askUser(host));
        try {
            wait();
        } catch (InterruptedException e) {
            Log.d(UserLoggerInner.class.getSimpleName(), e.getMessage(), e);
        }
    }

    /**
     * Prompts the user for their username and password.
     *
     * @param host The server the user will be logging into.
     */
    private void askUser(String host) {
        UserPassDialog dialog = new UserPassDialog(this.activity, host);
        model = dialog.getModel();
        model.addObserver((model, property) -> onUpdate(model, property));
        dialog.show();
    }

    /**
     * Called when the UserPassDialog model is updated.
     *
     * @param model    The model.
     * @param property The property that changed in the model.
     */
    private synchronized void onUpdate(Object model, Object property) {
        if (UserPassModel.PASSWORD_PROP.equals(property)) {
            notify();
        }
    }
}

@@ -1322,12 +1322,17 @@
 .get
-Host
+Authority
 ();%0A
@@ -1591,32 +1591,36 @@
 ) %7B%0A            
+for(
 Account account 
@@ -1619,17 +1619,17 @@
 account 
-=
+:
  account
@@ -1633,13 +1633,13 @@
 unts
-%5B0%5D;%0A
+) %7B%0A 
     
@@ -1650,23 +1650,25 @@
     
+   
 String
- userName
+%5B%5D split
  = a
@@ -1678,18 +1678,131 @@
 unt.name
+.split(%22 - %22)
 ;%0A
+                if(split%5B1%5D.equals(host)) %7B%0A                    String userName = split%5B0%5D;%0A        
         
@@ -1856,24 +1856,32 @@
 d(account);%0A
+        
             
@@ -1942,32 +1942,91 @@
 ame, password);%0A
+                    break;%0A                %7D%0A            %7D%0A
         %7D%0A%0A     
@@ -2360,32 +2360,32 @@
 uthenticated) %7B%0A
-
                 
@@ -2429,16 +2429,31 @@
 username
+ + %22 - %22 + host
 , MAPCAC

handle multiple accounts for multiple servers