<commit_before><?php
/**
 * Join the rewards program
 */

namespace Minds\Core\Rewards;

use Minds\Core\Di\Di;
use Minds\Core;
use Minds\Core\Referrals\Referral;
use Minds\Core\SMS\Exceptions\VoIpPhoneException;
use Minds\Entities\User;
use Minds\Core\Util\BigNumber;

class Join
{
    /** @var TwoFactor $twofactor */
    private $twofactor;

    /** @var Core\SMS\SMSServiceInterface $sms */
    private $sms;

    /** @var PhoneNumberUtil $libphonenumber */
    private $libphonenumber;

    /** @var User $user */
    private $user;

    /** @var int $number */
    private $number;

    /** @var int $code */
    private $code;

    /** @var string $secret */
    private $secret;

    /** @var Config $config */
    private $config;

    /** @var ReferralValidator */
    private $validator;

    /** @var OfacBlacklist */
    private $ofacBlacklist;

    /** @var TestnetBalance */
    private $testnetBalance;

    /** @var Call */
    private $db;

    /** @var ReferralDelegate $eventsDelegate */
    private $referralDelegate;

    public function __construct(
        $twofactor = null,
        $sms = null,
        $libphonenumber = null,
        $config = null,
        $validator = null,
        $db = null,
        $joinedValidator = null,
        $ofacBlacklist = null,
        $testnetBalance = null,
        $referralDelegate = null
    ) {
        $this->twofactor = $twofactor ?: Di::_()->get('Security\TwoFactor');
        $this->sms = $sms ?: Di::_()->get('SMS');
        $this->libphonenumber = $libphonenumber ?: \libphonenumber\PhoneNumberUtil::getInstance();
        $this->config = $config ?: Di::_()->get('Config');
        $this->validator = $validator ?: Di::_()->get('Rewards\ReferralValidator');
        $this->db = $db ?: new Core\Data\Call('entities_by_time');
        $this->joinedValidator = $joinedValidator ?: Di::_()->get('Rewards\JoinedValidator');
        $this->ofacBlacklist = $ofacBlacklist ?: Di::_()->get('Rewards\OfacBlacklist');
        $this->testnetBalance = $testnetBalance ?: Di::_()->get('Blockchain\Wallets\OffChain\TestnetBalance');
        $this->referralDelegate = $referralDelegate ?: new Delegates\ReferralDelegate;
    }

    public function setUser(&$user)
    {
        $this->user = $user;
        return $this;
    }

    public function setNumber($number)
    {
        if ($this->ofacBlacklist->isBlacklisted($number)) {
            throw new \Exception('Because your country is currently listed on the OFAC sanctions list you are unable to earn rewards or purchase tokens');
        }
        $proto = $this->libphonenumber->parse("+$number");
        $this->number = $this->libphonenumber->format($proto, \libphonenumber\PhoneNumberFormat::E164);

        if (md5($this->number) === 'cd6fd474ebbc6f5322d4267a85648ebe') {
            error_log("Bad user found: {$this->user->username}");
            throw new \Exception("Stop.");
        }
        return $this;
    }

    public function setCode($code)
    {
        $this->code = $code;
        return $this;
    }

    public function setSecret($secret)
    {
        $this->secret = $secret;
        return $this;
    }

    /**
     * @return string
     * @throws VoIpPhoneException
     */
    public function verify()
    {
        $secret = $this->twofactor->createSecret();
        $code = $this->twofactor->getCode($secret);

        $user_guid = $this->user->guid;
        $this->db->insert("rewards:verificationcode:$user_guid", compact('code', 'secret'));

        if (!$this->sms->verify($this->number)) {
            throw new VoIpPhoneException();
        }

        $this->sms->send($this->number, $code);

        return $secret;
    }

    public function resendCode()
    {
        $user_guid = $this->user->guid;
        $row = $this->db->getRow("rewards:verificationcode:$user_guid");

        if (!empty($row)) {
            if (!$this->sms->verify($this->number)) {
                throw new VoIpPhoneException();
            }
            $this->sms->send($this->number, $row['code']);

            return $row['secret'];
        }
    }

    public function confirm()
    {
        if ($this->user->getPhoneNumberHash()) {
            return false; //already joined<commit_msg>(chore): provide username in SMS<commit_after><?php
/**
 * Join the rewards program
 */

namespace Minds\Core\Rewards;

use Minds\Core\Di\Di;
use Minds\Core;
use Minds\Core\Referrals\Referral;
use Minds\Core\SMS\Exceptions\VoIpPhoneException;
use Minds\Entities\User;
use Minds\Core\Util\BigNumber;

class Join
{
    /** @var TwoFactor $twofactor */
    private $twofactor;

    /** @var Core\SMS\SMSServiceInterface $sms */
    private $sms;

    /** @var PhoneNumberUtil $libphonenumber */
    private $libphonenumber;

    /** @var User $user */
    private $user;

    /** @var int $number */
    private $number;

    /** @var int $code */
    private $code;

    /** @var string $secret */
    private $secret;

    /** @var Config $config */
    private $config;

    /** @var ReferralValidator */
    private $validator;

    /** @var OfacBlacklist */
    private $ofacBlacklist;

    /** @var TestnetBalance */
    private $testnetBalance;

    /** @var Call */
    private $db;

    /** @var ReferralDelegate $eventsDelegate */
    private $referralDelegate;

    public function __construct(
        $twofactor = null,
        $sms = null,
        $libphonenumber = null,
        $config = null,
        $validator = null,
        $db = null,
        $joinedValidator = null,
        $ofacBlacklist = null,
        $testnetBalance = null,
        $referralDelegate = null
    ) {
        $this->twofactor = $twofactor ?: Di::_()->get('Security\TwoFactor');
        $this->sms = $sms ?: Di::_()->get('SMS');
        $this->libphonenumber = $libphonenumber ?: \libphonenumber\PhoneNumberUtil::getInstance();
        $this->config = $config ?: Di::_()->get('Config');
        $this->validator = $validator ?: Di::_()->get('Rewards\ReferralValidator');
        $this->db = $db ?: new Core\Data\Call('entities_by_time');
        $this->joinedValidator = $joinedValidator ?: Di::_()->get('Rewards\JoinedValidator');
        $this->ofacBlacklist = $ofacBlacklist ?: Di::_()->get('Rewards\OfacBlacklist');
        $this->testnetBalance = $testnetBalance ?: Di::_()->get('Blockchain\Wallets\OffChain\TestnetBalance');
        $this->referralDelegate = $referralDelegate ?: new Delegates\ReferralDelegate;
    }

    public function setUser(&$user)
    {
        $this->user = $user;
        return $this;
    }

    public function setNumber($number)
    {
        if ($this->ofacBlacklist->isBlacklisted($number)) {
            throw new \Exception('Because your country is currently listed on the OFAC sanctions list you are unable to earn rewards or purchase tokens');
        }
        $proto = $this->libphonenumber->parse("+$number");
        $this->number = $this->libphonenumber->format($proto, \libphonenumber\PhoneNumberFormat::E164);

        if (md5($this->number) === 'cd6fd474ebbc6f5322d4267a85648ebe') {
            error_log("Bad user found: {$this->user->username}");
            throw new \Exception("Stop.");
        }
        return $this;
    }

    public function setCode($code)
    {
        $this->code = $code;
        return $this;
    }

    public function setSecret($secret)
    {
        $this->secret = $secret;
        return $this;
    }

    /**
     * @return string
     * @throws VoIpPhoneException
     */
    public function verify()
    {
        $secret = $this->twofactor->createSecret();
        $code = $this->twofactor->getCode($secret);

        $user_guid = $this->user->guid;
        $this->db->insert("rewards:verificationcode:$user_guid", compact('code', 'secret'));

        if (!$this->sms->verify($this->number)) {
            throw new VoIpPhoneException();
        }

        $username = $this->user->getUsername();

        $this->sms->send($this->number, "Minds Rewards Code for @$username: $code");

        return $secret;
    }

    public function resendCode()
    {
        $user_guid = $this->user->guid;
        $username = $this->user->getUsername();
        $row = $this->db->getRow("rewards:verificationcode:$user_guid");

        if (!empty($row)) {
            if (!$this->sms->verify($this->number)) {
                throw new VoIpPhoneException();
            }

            $code = $row['code'];
            $this->sms->send($this->number, "Minds Rewards Code for @$username: $code");

            return $row['secret'];
        }
    }

    public function confirm()
    {
        if ($this->user->getPhoneNumberHash()) {
            return false; //already joined
{'fraction_non_alphanumeric': 0.15985687903970452, 'fraction_numerical': 0.0050784856879039705, 'mean_word_length': 2.4715544871794872, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 119, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3584951', 'n_tokens_mistral': 2704, 'n_tokens_neox': 2634, 'n_words': 527}