<?php

class UserPeer
{

    // Singleton object. Leave $me alone.
    private static $me;

    static function create($username, $password, $email, $title, $firstname, $lastname, $accType = 'user')
    {
        $dbInsert                 = new DBObject("users", array("username", "password", "email",
            "title", "firstname", "lastname", "datecreated",
            "createdip", "status", "level_id", "paymentTracker", "identifier")
        );
        $dbInsert->username       = $username;
        $dbInsert->password       = MD5($password);
        $dbInsert->email          = $email;
        $dbInsert->title          = $title;
        $dbInsert->firstname      = $firstname;
        $dbInsert->lastname       = $lastname;
        $dbInsert->datecreated    = coreFunctions::sqlDateTime();
        $dbInsert->createdip      = coreFunctions::getUsersIPAddress();
        $dbInsert->status         = 'active';
        $dbInsert->level_id       = 1;
        $dbInsert->paymentTracker = MD5(time() . $username);
        $dbInsert->identifier     = MD5(time() . $username . $password);
        if ($dbInsert->insert())
        {
            return $dbInsert;
        }

        return false;
    }

    static function createPasswordResetHash($userId)
    {
        $user = true;

        // make sure it doesn't already exist on an account
        while ($user != false)
        {
            // create hash
            $hash = MD5(microtime() . $userId);

            // lookup by hash
            $user = self::loadUserByPasswordResetHash($hash);
        }

        // update user with hash
        $db = Database::getDatabase(true);
        $db->query('UPDATE users SET passwordResetHash = :passwordResetHash WHERE id = :id', array('passwordResetHash' => $hash, 'id'                => $userId));

        return $hash;
    }

    static function loadUserById($id)
    {
        $userObj = new User();
        $userObj->select($id, 'id');
        if (!$userObj->ok())
        {
            return false;
        }

        return $userObj;
    }

    static function loadUserByUsername($username)
    {
        $userObj = new User();
        $userObj->select($username, 'username');
        if (!$userObj->ok())
        {
            return false;
        }

        return $userObj;
    }

    static function loadUserByPaymentTracker($paymentTracker)
    {
        $userObj = new User();
        $userObj->select($paymentTracker, 'paymentTracker');
        if (!$userObj->ok())
        {
            return false;
        }

        return $userObj;
    }

    static function loadUserByEmailAddress($email)
    {
        $userObj = new User();
        $userObj->select($email, 'email');
        if (!$userObj->ok())
        {
            return false;
        }

        return $userObj;
    }

    static function loadUserByPasswordResetHash($hash)
    {
        $userObj = new User();
        $userObj->select($hash, 'passwordResetHash');
        if (!$userObj->ok())
        {
            return false;
        }

        return $userObj;
    }

    static function loadUserByIdentifier($identifier)
    {
        $userObj = new User();
        $userObj->select($identifier, 'identifier');
        if (!$userObj->ok())
        {
            return false;
        }

        return $userObj;
    }

    static function upgradeUser($userId, $days)
    {
        // load user
        $user = UserPeer::loadUserById($userId);

        // upgrade user
        $newExpiryDate = strtotime('+' . $days . ' days');

        // exntend user
        if ($user->level_id >= 2)
        {
            // add onto existing period
            $existingExpiryDate = strtotime($user->paidExpiryDate);

            // if less than today just revert to now
            if ($existingExpiryDate < time())
            {
                $existingExpiryDate = time();
            }

            $newExpiryDate = (int) $existingExpiryDate + (int) ($days * (60 * 60 * 24));
        }

        // figure out new account type
        $newUserType = 2;
        if ($user->level_id > 2)
        {
            $newUserType = $user->level_id;
        }

        // update user account to premium
        $dbUpdate                 = new DBObject("users", array("level_id", "lastPayment", "paidExpiryDate"), 'id');
        $dbUpdate->level_id       = $newUserType;
        $dbUpdate->lastPayment    = date("Y-m-d H:i:s", time());
        $dbUpdate->paidExpiryDate = date("Y-m-d H:i:s", $newExpiryDate);
        $dbUpdate->id             = $userId;
        $effectedRows             = $dbUpdate->update();
        if ($effectedRows === false)
        {
            // failed to update user
            return false;
        }

        return true;
    }

    static function downgradeExpiredAccounts()
    {
        // connect db
        $db = Database::getDatabase(true);

        // downgrade paid accounts
        $sQL = 'UPDATE users SET level_id = 1 WHERE level_id = 2 AND UNIX_TIMESTAMP(paidExpiryDate) < ' . time();
        $rs  = $db->query($sQL);
    }

    static function getLevelLabel($levelId)
    {
        // connect db
        $db = Database::getDatabase(true);

        return $db->getValue('SELECT label FROM user_level WHERE level_id = ' . (int) $levelId . ' LIMIT 1');
    }

    static function getAcceptedFileTypes()
    {
        $rs = array();
        if (strlen(trim(SITE_CONFIG_ACCEPTED_UPLOAD_FILE_TYPES)) > 0)
        {
            $fileTypes = explode(";", trim(SITE_CONFIG_ACCEPTED_UPLOAD_FILE_TYPES));
            foreach ($fileTypes AS $fileType)
            {
                if (strlen(trim($fileType)))
                {
                    $rs[] = strtolower(trim($fileType));
                }
            }
        }
        sort($rs);

        return $rs;
    }

    static function getRemainingFilesToday()
    {
        if ((int) SITE_CONFIG_MAX_FILES_PER_DAY == 0)
        {
            return 10000;
        }

        $userIP         = coreFunctions::getUsersIPAddress();
        $db             = Database::getDatabase(true);
        $totalUploads   = (int) $db->getValue('SELECT COUNT(id) AS total FROM file WHERE DATE(uploadedDate) = DATE(NOW()) AND uploadedIP = ' . $db->quote($userIP));
        $totalRemaining = (int) SITE_CONFIG_MAX_FILES_PER_DAY - $totalUploads;

        return $totalRemaining >= 0 ? $totalRemaining : 0;
    }

    static function showSiteAdverts($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return SITE_CONFIG_FREE_USER_SHOW_ADVERTS == 'yes' ? true : false;
            // non user
            case 0:
                return SITE_CONFIG_NON_USER_SHOW_ADVERTS == 'yes' ? true : false;
            // paid & admin users
            default:
                return SITE_CONFIG_PAID_USER_SHOW_ADVERTS == 'yes' ? true : false;
        }
    }

    static function getAllowedToUpload($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return SITE_CONFIG_FREE_USER_ALLOW_UPLOADS == 'yes' ? true : false;
            // non user
            case 0:
                return SITE_CONFIG_NON_USER_ALLOW_UPLOADS == 'yes' ? true : false;
            // paid user
            case 2:
                return SITE_CONFIG_PAID_USER_ALLOW_UPLOADS == 'yes' ? true : false;
            // other users
            default:
                return true;
        }
    }

    static function getMaxDailyDownloads($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return (int) SITE_CONFIG_FREE_USER_MAX_DOWNLOADS_PER_DAY;
            // non user
            case 0:
                return (int) SITE_CONFIG_NON_USER_MAX_DOWNLOADS_PER_DAY;
            // paid & admin users
            default:
                return (int) SITE_CONFIG_PREMIUM_USER_MAX_DOWNLOADS_PER_DAY;
        }
    }

    static function getMaxDownloadSize($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return (int) SITE_CONFIG_FREE_USER_MAX_DOWNLOAD_FILESIZE;
            // non user
            case 0:
                return (int) SITE_CONFIG_NON_USER_MAX_DOWNLOAD_FILESIZE;
            // paid & admin users
            default:
                return 0;
        }
    }

    static function getMaxDownloadSpeed($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return (int) SITE_CONFIG_FREE_USER_MAX_DOWNLOAD_SPEED;
            // non user
            case 0:
                return (int) SITE_CONFIG_NON_USER_MAX_DOWNLOAD_SPEED;
            // paid & admin users
            default:
                return (int) SITE_CONFIG_PREMIUM_USER_MAX_DOWNLOAD_SPEED;
        }
    }

    static function getMaxRemoteUrls($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return (int) SITE_CONFIG_FREE_USER_MAX_REMOTE_URLS;
            // non user
            case 0:
                return (int) SITE_CONFIG_NON_USER_MAX_REMOTE_URLS;
            // paid & admin users
            default:
                return (int) SITE_CONFIG_PREMIUM_USER_MAX_REMOTE_URLS;
        }
    }

    static function getMaxUploadFilesize($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return strlen(SITE_CONFIG_FREE_USER_MAX_UPLOAD_FILESIZE) ? SITE_CONFIG_FREE_USER_MAX_UPLOAD_FILESIZE : 0;
            // non user
            case 0:
                return strlen(SITE_CONFIG_NON_USER_MAX_UPLOAD_FILESIZE) ? SITE_CONFIG_NON_USER_MAX_UPLOAD_FILESIZE : 0;
            // paid & admin users
            default:
                return strlen(SITE_CONFIG_PREMIUM_USER_MAX_UPLOAD_FILESIZE) ? SITE_CONFIG_PREMIUM_USER_MAX_UPLOAD_FILESIZE : 0;
        }
    }

    static function showDownloadCaptcha($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return (SITE_CONFIG_FREE_USER_SHOW_CAPTCHA == 'yes') ? true : false;
            // non user
            case 0:
                return (SITE_CONFIG_NON_USER_SHOW_CAPTCHA == 'yes') ? true : false;
            // paid & admin users
            default:
                return false;
        }
    }

    static function getWaitTimeBetweenDownloads($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return (int) SITE_CONFIG_FREE_USER_WAIT_BETWEEN_DOWNLOADS;
            // non user
            case 0:
                return (int) SITE_CONFIG_NON_USER_WAIT_BETWEEN_DOWNLOADS;
            // paid & admin users
            default:
                return 0;
        }
    }

    static function enableUpgradePage($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return SITE_CONFIG_FREE_USER_SHOW_UPGRADE_PAGE;
            // non user
            case 0:
                return SITE_CONFIG_NON_USER_SHOW_UPGRADE_PAGE;
            // paid & admin users
            default:
                return SITE_CONFIG_PAID_USER_SHOW_UPGRADE_PAGE;
        }
    }

    static function getMaxDownloadThreads($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        switch ($levelId)
        {
            // free user
            case 1:
                return (int) SITE_CONFIG_FREE_USER_MAX_DOWNLOAD_THREADS;
            // non user
            case 0:
                return (int) SITE_CONFIG_NON_USER_MAX_DOWNLOAD_THREADS;
            // paid & admin users
            default:
                return (int) SITE_CONFIG_PAID_USER_MAX_DOWNLOAD_THREADS;
        }
    }

    static function getMaxFileStorage($userId = null)
    {
        $fallback = 1024 * 1024 * 1024 * 1024 * 5; // 5TB fallback
        $limit    = $fallback;
        $Auth     = null;
        $userLevel = 0;
        if ($userId === null)
        {
            $Auth   = Auth::getAuth();
            $userId = $Auth->id;
        }

        if ($userId !== null)
        {
            if ($Auth)
            {
                $userLevel            = $Auth->level_id;
                $storageLimitOverride = $Auth->user->storageLimitOverride;
            }
            else
            {
                $user                 = UserPeer::loadUserById($userId);
                $userLevel            = $user->level_id;
                $storageLimitOverride = $user->storageLimitOverride;
            }
        }

        // limit based on account type
        if ($userLevel <= 1)
        {
            $limit = ((strlen(SITE_CONFIG_FREE_USER_MAXIMUM_STORAGE) == 0) || (SITE_CONFIG_FREE_USER_MAXIMUM_STORAGE == 0)) ? null : SITE_CONFIG_FREE_USER_MAXIMUM_STORAGE;
        }
        else
        {
            $limit = ((strlen(SITE_CONFIG_PREMIUM_USER_MAXIMUM_STORAGE) == 0) || (SITE_CONFIG_PREMIUM_USER_MAXIMUM_STORAGE == 0)) ? null : SITE_CONFIG_PREMIUM_USER_MAXIMUM_STORAGE;
        }

        // check for limit override
        if ((strlen($storageLimitOverride)) && ($storageLimitOverride > 0))
        {
            $limit = $storageLimitOverride;
        }

        // for unlimited
        if ($limit == 0)
        {
            $limit = null;
        }

        return $limit;
    }

    static function getTotalWaitingTime($levelId = null)
    {
        if ($levelId === null)
        {
            $Auth    = Auth::getAuth();
            $levelId = $Auth->level_id;
        }

        // lookup total waiting time
        $db        = Database::getDatabase();
        $sQL       = 'SELECT additional_settings FROM download_page WHERE user_level_id = ' . (int) $levelId;
        $rows      = $db->getRows($sQL);
        $totalTime = 0;
        if ($rows)
        {
            foreach ($rows AS $row)
            {
                $additionalSettings = $row['additional_settings'];
                if (strlen($additionalSettings))
                {
                    $additionalSettingsArr = json_decode($additionalSettings, true);
                    if (isset($additionalSettingsArr['download_wait']))
                    {
                        $totalTime = $totalTime + (int) $additionalSettingsArr['download_wait'];
                    }
                }
            }
        }

        return $totalTime;
    }

    static function getAvailableFileStorage($userId = null)
    {
        $fallback = 1024 * 1024 * 1024 * 1024 * 5; // 5TB fallback
        if ($userId === null)
        {
            $Auth    = Auth::getAuth();
            if ($Auth->loggedIn() == true)
            {
                $Auth   = Auth::getAuth();
                $userId = $Auth->id;
            }
            else
            {
                return $fallback;
            }
        }
        $maxFileStorage = self::getMaxFileStorage($userId);
        if (($maxFileStorage === null) || ($maxFileStorage === $fallback)) // unlimited users
        {
            return null;
        }

        // calculate total user
        $totalUsed = file::getTotalActiveFileSizeByUser($userId);
        if ($totalUsed > $maxFileStorage)
        {
            return 0;
        }

        return $maxFileStorage - $totalUsed;
    }

}
