/**
* Returns user data after he authenticate via hybridauth 
*
* Steps:
*    1. Grab the user profile from hybridauth
*    2. Run Bouncer::Filters if enabled (domains, emails, profiles urls)
*    3. Check if user exist in database by looking for the couple (Provider name, Provider user ID) or verified email
*    4. Deletegate detection of user id to custom functions / hooks
*    5. If Bouncer::Profile Completion is enabled and user didn't exist, we require the user to complete the registration (user name & email) 
*/
function wsl_process_login_get_user_data($provider, $redirect_to)
{
    // HOOKABLE:
    do_action("wsl_process_login_get_user_data_start", $provider, $redirect_to);
    $user_id = null;
    $config = null;
    $hybridauth = null;
    $adapter = null;
    $hybridauth_user_profile = null;
    $requested_user_login = '';
    $requested_user_email = '';
    /* 1. Grab the user profile from social network */
    if (!(isset($_SESSION['wsl::userprofile']) && $_SESSION['wsl::userprofile'] && ($hybridauth_user_profile = json_decode($_SESSION['wsl::userprofile'])))) {
        $hybridauth_user_profile = wsl_process_login_request_user_social_profile($provider);
        $_SESSION['wsl::userprofile'] = json_encode($hybridauth_user_profile);
    }
    $adapter = wsl_process_login_get_provider_adapter($provider);
    $hybridauth_user_email = sanitize_email($hybridauth_user_profile->email);
    /* 2. Run Bouncer::Filters if enabled (domains, emails, profiles urls) */
    // Bouncer::Filters by emails domains name
    if (get_option('wsl_settings_bouncer_new_users_restrict_domain_enabled') == 1) {
        if (empty($hybridauth_user_email)) {
            return wsl_process_login_render_notice_page(_wsl__(get_option('wsl_settings_bouncer_new_users_restrict_domain_text_bounce'), 'wordpress-social-login'));
        }
        $list = get_option('wsl_settings_bouncer_new_users_restrict_domain_list');
        $list = preg_split('/$\\R?^/m', $list);
        $current = strstr($hybridauth_user_email, '@');
        $shall_pass = false;
        foreach ($list as $item) {
            if (trim(strtolower("@{$item}")) == strtolower($current)) {
                $shall_pass = true;
            }
        }
        if (!$shall_pass) {
            return wsl_process_login_render_notice_page(_wsl__(get_option('wsl_settings_bouncer_new_users_restrict_domain_text_bounce'), 'wordpress-social-login'));
        }
    }
    // Bouncer::Filters by e-mails addresses
    if (get_option('wsl_settings_bouncer_new_users_restrict_email_enabled') == 1) {
        if (empty($hybridauth_user_email)) {
            return wsl_process_login_render_notice_page(_wsl__(get_option('wsl_settings_bouncer_new_users_restrict_email_text_bounce'), 'wordpress-social-login'));
        }
        $list = get_option('wsl_settings_bouncer_new_users_restrict_email_list');
        $list = preg_split('/$\\R?^/m', $list);
        $shall_pass = false;
        foreach ($list as $item) {
            if (trim(strtolower($item)) == strtolower($hybridauth_user_email)) {
                $shall_pass = true;
            }
        }
        if (!$shall_pass) {
            return wsl_process_login_render_notice_page(_wsl__(get_option('wsl_settings_bouncer_new_users_restrict_email_text_bounce'), 'wordpress-social-login'));
        }
    }
    // Bouncer::Filters by profile urls
    if (get_option('wsl_settings_bouncer_new_users_restrict_profile_enabled') == 1) {
        $list = get_option('wsl_settings_bouncer_new_users_restrict_profile_list');
        $list = preg_split('/$\\R?^/m', $list);
        $shall_pass = false;
        foreach ($list as $item) {
            if (trim(strtolower($item)) == strtolower($hybridauth_user_profile->profileURL)) {
                $shall_pass = true;
            }
        }
        if (!$shall_pass) {
            return wsl_process_login_render_notice_page(_wsl__(get_option('wsl_settings_bouncer_new_users_restrict_profile_text_bounce'), 'wordpress-social-login'));
        }
    }
    /* 3. Check if user exist in database by looking for the couple (Provider name, Provider user ID) or verified email */
    // check if user already exist in wslusersprofiles
    $user_id = (int) wsl_get_stored_hybridauth_user_id_by_provider_and_provider_uid($provider, $hybridauth_user_profile->identifier);
    // if not found in wslusersprofiles, then check his verified email
    if (!$user_id && !empty($hybridauth_user_profile->emailVerified)) {
        // check if the verified email exist in wp_users
        $user_id = (int) wsl_wp_email_exists($hybridauth_user_profile->emailVerified);
        // check if the verified email exist in wslusersprofiles
        if (!$user_id) {
            $user_id = (int) wsl_get_stored_hybridauth_user_id_by_email_verified($hybridauth_user_profile->emailVerified);
        }
    }
    /* 4 Deletegate detection of user id to custom filters hooks */
    // HOOKABLE:
    $user_id = apply_filters('wsl_hook_process_login_alter_user_id', $user_id, $provider, $hybridauth_user_profile);
    /* 5. If Bouncer::Profile Completion is enabled and user didn't exist, we require the user to complete the registration (user name & email) */
    if (!$user_id) {
        // Bouncer :: Accept new registrations?
        if (get_option('wsl_settings_bouncer_registration_enabled') == 2) {
            return wsl_process_login_render_notice_page(_wsl__("Registration is now closed.", 'wordpress-social-login'));
        }
        // Bouncer::Accounts linking/mapping
        // > > not implemented yet! Planned for WSL 2.3
        if (get_option('wsl_settings_bouncer_accounts_linking_enabled') == 1) {
            do {
                list($shall_pass, $user_id, $requested_user_login, $requested_user_email) = wsl_process_login_new_users_gateway($provider, $redirect_to, $hybridauth_user_profile);
            } while (!$shall_pass);
        } elseif (get_option('wsl_settings_bouncer_profile_completion_require_email') == 1 && empty($hybridauth_user_email) || get_option('wsl_settings_bouncer_profile_completion_change_username') == 1) {
            do {
                list($shall_pass, $requested_user_login, $requested_user_email) = wsl_process_login_complete_registration($provider, $redirect_to, $hybridauth_user_profile);
            } while (!$shall_pass);
        }
    }
    /* 6. returns user data */
    return array($user_id, $adapter, $hybridauth_user_profile, $requested_user_login, $requested_user_email);
}
function wsl_process_login_hybridauth_authenticate($provider, $redirect_to)
{
    try {
        # Hybrid_Auth already used?
        if (class_exists('Hybrid_Auth', false)) {
            return wsl_render_notices_pages(_wsl__("Error: Another plugin seems to be using HybridAuth Library and made WordPress Social Login unusable. We recommand to find this plugin and to kill it with fire!", 'wordpress-social-login'));
        }
        // load hybridauth
        require_once WORDPRESS_SOCIAL_LOGIN_ABS_PATH . "/hybridauth/Hybrid/Auth.php";
        // build required configuratoin for this provider
        if (!get_option('wsl_settings_' . $provider . '_enabled')) {
            throw new Exception('Unknown or disabled provider');
        }
        $config = array();
        $config["providers"] = array();
        $config["providers"][$provider] = array();
        $config["providers"][$provider]["enabled"] = true;
        // provider application id ?
        if (get_option('wsl_settings_' . $provider . '_app_id')) {
            $config["providers"][$provider]["keys"]["id"] = get_option('wsl_settings_' . $provider . '_app_id');
        }
        // provider application key ?
        if (get_option('wsl_settings_' . $provider . '_app_key')) {
            $config["providers"][$provider]["keys"]["key"] = get_option('wsl_settings_' . $provider . '_app_key');
        }
        // provider application secret ?
        if (get_option('wsl_settings_' . $provider . '_app_secret')) {
            $config["providers"][$provider]["keys"]["secret"] = get_option('wsl_settings_' . $provider . '_app_secret');
        }
        // create an instance for Hybridauth
        $hybridauth = new Hybrid_Auth($config);
        // try to authenticate the selected $provider
        if ($hybridauth->isConnectedWith($provider)) {
            $adapter = $hybridauth->getAdapter($provider);
            $hybridauth_user_profile = $adapter->getUserProfile();
            // check hybridauth user email
            $hybridauth_user_id = (int) wsl_get_user_by_meta($provider, $hybridauth_user_profile->identifier);
            $hybridauth_user_email = sanitize_email($hybridauth_user_profile->email);
            $hybridauth_user_login = sanitize_user($hybridauth_user_profile->displayName);
            $request_user_login = "";
            $request_user_email = "";
            # {{{ linking new accounts
            // Bouncer :: Accounts Linking is enabled
            if (get_option('wsl_settings_bouncer_linking_accounts_enabled') == 1) {
                // if user is linking account
                // . we DO import contacts
                // . we DO store the user profile
                //
                // . we DONT create another entry on user table
                // . we DONT create nor update his data on usermeata table
                if ($_REQUEST['action'] == "wordpress_social_link") {
                    global $current_user;
                    get_currentuserinfo();
                    $user_id = $current_user->ID;
                    return wsl_process_login_authenticate_wp_user_linked_account($user_id, $provider, $redirect_to, $adapter, $hybridauth_user_profile);
                }
                // check if connected user is linked account
                $linked_account = wsl_get_user_linked_account_by_provider_and_identifier($provider, $hybridauth_user_profile->identifier);
                // if linked account found, we connect the actual user
                if ($linked_account) {
                    if (count($linked_account) > 1) {
                        return wsl_render_notices_pages(_wsl__("This {$provider} is linked to many accounts!", 'wordpress-social-login'));
                    }
                    $user_id = $linked_account[0]->user_id;
                    if (!$user_id) {
                        return wsl_render_notices_pages(_wsl__("Something wrong!", 'wordpress-social-login'));
                    }
                    return wsl_process_login_authenticate_wp_user($user_id, $provider, $redirect_to, $adapter, $hybridauth_user_profile);
                }
            }
            # }}} linking new accounts
            # {{{ module Bouncer
            // Bouncer :: Filters by emails domains name
            if (get_option('wsl_settings_bouncer_new_users_restrict_domain_enabled') == 1) {
                if (empty($hybridauth_user_email)) {
                    return wsl_render_notices_pages(get_option('wsl_settings_bouncer_new_users_restrict_domain_text_bounce'));
                }
                $list = get_option('wsl_settings_bouncer_new_users_restrict_domain_list');
                $list = preg_split('/$\\R?^/m', $list);
                $current = strstr($hybridauth_user_email, '@');
                $shall_pass = false;
                foreach ($list as $item) {
                    if (trim(strtolower("@{$item}")) == strtolower($current)) {
                        $shall_pass = true;
                    }
                }
                if (!$shall_pass) {
                    return wsl_render_notices_pages(get_option('wsl_settings_bouncer_new_users_restrict_domain_text_bounce'));
                }
            }
            // Bouncer :: Filters by e-mails addresses
            if (get_option('wsl_settings_bouncer_new_users_restrict_email_enabled') == 1) {
                if (empty($hybridauth_user_email)) {
                    return wsl_render_notices_pages(get_option('wsl_settings_bouncer_new_users_restrict_email_text_bounce'));
                }
                $list = get_option('wsl_settings_bouncer_new_users_restrict_email_list');
                $list = preg_split('/$\\R?^/m', $list);
                $shall_pass = false;
                foreach ($list as $item) {
                    if (trim(strtolower($item)) == strtolower($hybridauth_user_email)) {
                        $shall_pass = true;
                    }
                }
                if (!$shall_pass) {
                    return wsl_render_notices_pages(get_option('wsl_settings_bouncer_new_users_restrict_email_text_bounce'));
                }
            }
            // Bouncer :: Filters by profile urls
            if (get_option('wsl_settings_bouncer_new_users_restrict_profile_enabled') == 1) {
                $list = get_option('wsl_settings_bouncer_new_users_restrict_profile_list');
                $list = preg_split('/$\\R?^/m', $list);
                $shall_pass = false;
                foreach ($list as $item) {
                    if (trim(strtolower($item)) == strtolower($hybridauth_user_profile->profileURL)) {
                        $shall_pass = true;
                    }
                }
                if (!$shall_pass) {
                    return wsl_render_notices_pages(get_option('wsl_settings_bouncer_new_users_restrict_profile_text_bounce'));
                }
            }
            // if user do not exist
            if (!$hybridauth_user_id) {
                // Bouncer :: Accept new registrations
                if (get_option('wsl_settings_bouncer_registration_enabled') == 2) {
                    return wsl_render_notices_pages(_wsl__("registration is now closed!", 'wordpress-social-login'));
                }
                // Bouncer :: Profile Completion
                if (get_option('wsl_settings_bouncer_profile_completion_require_email') == 1 && empty($hybridauth_user_email) || get_option('wsl_settings_bouncer_profile_completion_change_username') == 1) {
                    do {
                        list($shall_pass, $request_user_login, $request_user_email) = wsl_process_login_complete_registration($provider, $redirect_to, $hybridauth_user_email, $hybridauth_user_login);
                    } while (!$shall_pass);
                }
            }
            # }}} module Bouncer
        } else {
            throw new Exception('User not connected with ' . $provider . '!');
        }
    } catch (Exception $e) {
        return wsl_render_notices_pages(sprintf(_wsl__("Unspecified error. #%d", 'wordpress-social-login'), $e->getCode()));
    }
    $user_id = null;
    // if the user email is verified, then try to map to legacy account if exist
    // > Currently only Facebook, Google, Yahaoo and Foursquare do provide the verified user email.
    if (!empty($hybridauth_user_profile->emailVerified)) {
        $user_id = (int) email_exists($hybridauth_user_profile->emailVerified);
    }
    // try to get user by meta if not
    if (!$user_id) {
        $user_id = (int) wsl_get_user_by_meta($provider, $hybridauth_user_profile->identifier);
    }
    return array($user_id, $adapter, $hybridauth_user_profile, $hybridauth_user_id, $hybridauth_user_email, $request_user_login, $request_user_email);
}