<commit_before><?php

namespace Laelaps\Bundle\FacebookAuthentication\Security;

use Laelaps\Bundle\Facebook\FacebookAdapterAwareInterface;
use Laelaps\Bundle\Facebook\FacebookAdapterAwareTrait;
use Laelaps\Bundle\FacebookAuthentication\Exception\InvalidUser as InvalidUserException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

abstract class FacebookUserProvider implements FacebookAdapterAwareInterface, UserProviderInterface
{
    use FacebookAdapterAwareTrait;

    /**
     * @var bool
     */
    private $shouldCreateUserByDefault = true;

    /**
     * @var array
     */
    private $usernameShouldCreateStatus = [];

    /**
     * @var array
     */
    private static $cachedFacebookData = [];

    /**
     * @param string $username
     * @return null|\Symfony\Component\Security\Core\User\UserInterface
     */
    abstract protected function doLoadUserByUsername($username);

    /**
     * @param array $facebookData
     * @return void
     */
    abstract public function createUserByFacebookData(array $facebookData);

    /**
     * @param string $username
     * @return array
     */
    protected function getCurrentUserFacebookData($username)
    {
        if (!isset(self::$cachedFacebookData[$username])) {
            self::$cachedFacebookData[$username] = $this->getFacebookAdapter()->api('/me');
        }

        return self::$cachedFacebookData[$username];
    }

    /**
     * @param string $username The username
     * @return \Symfony\Component\Security\Core\User\UserInterface
     * @throws \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
     * @throws \Laelaps\Bundle\FacebookAuthentication\Exception\InvalidUser
     */
    public function loadUserByUsername($username)
    {
        $user = $this->doLoadUserByUsername($username);

        if ($user instanceof UserInterface) {
            return $user;
        }

        if ($user) {
            throw new InvalidUserException($user);
        }

        if ($this->shouldCreateUser($username)) {
            $this->createUserByFacebookData($this->getCurrentUserFacebookData($username));
            $this->setShouldCreateUser($username, false);

            return $this->loadUserByUsername($username);
        }

        throw new UsernameNotFoundException(sprintf('Failed to load user by username: "%s"', $username));
    }

    /**
     * @param \Symfony\Component\Security\Core\User\UserInterface $user
     * @return \Symfony\Component\Security\Core\User\UserInterface
     * @throws \Symfony\Component\Security\Core\Exception\UnsupportedUserException
     */
    public function refreshUser(UserInterface $user)
    {
        $userClass = get_class($user);
        $username = $user->getUsername();

        if (!($this->supportsClass($userClass))) {
            throw new UnsupportedUserException(sprintf('User "%s" identified by username "%s" is not supported here.', $userClass, $username));
        }

        $this->setShouldCreateUser($username, false);

        return $this->loadUserByUsername($username);
    }

    /**
     * @param bool $shouldCreateUserByDefault
     * @return void
     */
    public function setShouldCreateUserByDefault($shouldCreateUserByDefault)
    {
        $this->shouldCreateUserByDefault = (bool) $shouldCreateUserByDefault;
    }

    /**
     * @param string $username
     * @return bool<commit_msg>FacebookUserProvider tweaks<commit_after><?php

namespace Laelaps\Bundle\FacebookAuthentication\Security;

use FacebookApiException;
use Laelaps\Bundle\Facebook\FacebookAdapterAwareInterface;
use Laelaps\Bundle\Facebook\FacebookAdapterAwareTrait;
use Laelaps\Bundle\FacebookAuthentication\Exception\InvalidUser as InvalidUserException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

abstract class FacebookUserProvider implements FacebookAdapterAwareInterface, UserProviderInterface
{
    use FacebookAdapterAwareTrait;

    /**
     * @var array
     */
    private $usernameShouldCreateStatus = [];

    /**
     * @var array
     */
    private static $cachedFacebookData = [];

    /**
     * @param string $username
     * @return null|\Symfony\Component\Security\Core\User\UserInterface
     */
    abstract protected function doLoadUserByUsername($username);

    /**
     * @param array $facebookData
     * @return void
     */
    abstract public function createUserByFacebookData(array $facebookData);

    /**
     * @return bool
     */
    abstract public function shouldCreateUserByDefault();

    /**
     * @param string $username
     * @return array|null
     */
    protected function getCurrentUserFacebookData($username)
    {
        if (!isset(self::$cachedFacebookData[$username])) {
            try {
                self::$cachedFacebookData[$username] = $this->getFacebookAdapter()->api('/me');
            } catch (FacebookApiException $e) {
                // $recovery = $this->getFacebookAdapter()->recover($e);
                // if ($recovery->shouldRetry()) {
                //     return $this->getCurrentUserFacebookData($username);
                // }

                // throw $e;
                return null;
            }
        }

        return self::$cachedFacebookData[$username];
    }

    /**
     * @param string $username The username
     * @return \Symfony\Component\Security\Core\User\UserInterface
     * @throws \Symfony\Component\Security\Core\Exception\UsernameNotFoundException
     * @throws \Laelaps\Bundle\FacebookAuthentication\Exception\InvalidUser
     */
    public function loadUserByUsername($username)
    {
        $user = $this->doLoadUserByUsername($username);

        if ($user instanceof UserInterface) {
            return $user;
        }

        if ($user) {
            throw new InvalidUserException($user);
        }

        if ($this->shouldCreateUser($username)) {
            $facebookData = $this->getCurrentUserFacebookData($username);
            if (is_array($facebookData)) {
                $this->createUserByFacebookData($facebookData);
                $this->setShouldCreateUser($username, false);

                return $this->loadUserByUsername($username);
            }
        }

        throw new UsernameNotFoundException(sprintf('Failed to load user by username: "%s"', $username));
    }

    /**
     * @param \Symfony\Component\Security\Core\User\UserInterface $user
     * @return \Symfony\Component\Security\Core\User\UserInterface
     * @throws \Symfony\Component\Security\Core\Exception\UnsupportedUserException
     */
    public function refreshUser(UserInterface $user)
    {
        $userClass = get_class($user);
        $username = $user->getUsername();

        if (!($this->supportsClass($userClass))) {
            throw new UnsupportedUserException(sprintf('User "%s" identified by username "%s" is not supported here.', $userClass, $username));
        }

        $this->setShouldCreateUser($username, false);

        return $this->loadUserByUsername($username);
    }

    /**
     * @param string $username
     * @param bool $shouldCreate
     * @return bool
     */
    public function setShouldCreateUser($username, $shouldCreate = true)
    {
        $this->usernameShouldCreateStatus[$username] = (bool) $shouldCreate;
    }

    /**
     * @param string $username
     * @return bool
{'fraction_non_alphanumeric': 0.11538461538461539, 'fraction_numerical': 0.0, 'mean_word_length': 2.952405322415558, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 43, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7128569', 'n_tokens_mistral': 2047, 'n_tokens_neox': 1981, 'n_words': 364}