<?php class UserManagement extends Device {

    const USERNAME='userimporter';
    const USERFULLNAME='User Importer';
    const USERDEFAULTPASSWORD='ChangeMe!';

    const USER_BAD_EMAIL_MESSAGE='Email address is invalid';
    const USER_BAD_USERNAME_MESSAGE='Username is invalid';
    const USER_NOT_FOUND='User not found';

	/**
	 * Given the user's full name and one/both of username and email address, creates the user.
	 * The user will be inactive and have a default password.
	 * @param array $user
	 * @return array
	 * @throws BadRequestException
	 * @throws ForbiddenException
	 * @throws NotFoundException
	 * @throws ServerException
	 */
    public static function createUser(array $user): array {
        Log::debug('In UserManagement::createUser');
        foreach($user as $k=>$v){
            Log::debug('- '.$k.'='.$v);
        }
        static::requireOneOf(['fullName','fullname'], $user);
        if(isset($user['fullname'])){ $user['fullName']=$user['fullname']; }
        static::requireOneOf(['email', 'username'], $user);
        session::becomeAdmin();
		session::setShowInactiveUsers(1);
        if (isset($user['username'])) {
            Log::info('Username is set, checking for existing user...');
            $existing = user::getByName($user['username']);
            if ($existing) {
                $existing['receiversId']=$existing['id'];
                Log::info('...exists. Returning existing user');
                Log::debug('Returning from UserManagement::createUser');
                return $existing;
            }
            Log::info('...does not exist. Validating supplied username...');
            if (!validator::isValid($user['username'], validator::USERNAME)) {
                throw new BadRequestException(static::USER_BAD_USERNAME_MESSAGE);
            }
            Log::info('...username is valid');
        } else {
            Log::info('Username is not set, generating temporary username...');
            $temporaryUsername = 'AUTO' . rand(10000000, 99999999);
            while (user::getByName($temporaryUsername)) {
                $temporaryUsername = 'AUTO' . rand(10000000, 99999999);
            }
            Log::info('Temporary username is '.$temporaryUsername);
            $user['username'] = $temporaryUsername;
        }
        if (isset($user['email'])) {
            Log::info('Checking for user with email '.$user['email'].' ...');
            $existing = user::getByProperty('email', $user['email']);
            if(!$existing && strtolower($user['email']) !== $user['email']){
                Log::info('...not found. Checking for user with email '.strtolower($user['email']).' ...');
                $existing = user::getByProperty('email', strtolower($user['email']));
            }
            if ($existing) {
                Log::info('...found existing user');
                $existing=$existing['rows'][0];
                $existing['receiversId']=$existing['id'];
                Log::debug('Returning from UserManagement::createUser');
                return $existing;
            }
            Log::info('...no existing user with email '.$user['email']);
            if (!validator::isValid($user['email'], validator::EMAIL)) {
                throw new BadRequestException(static::USER_BAD_EMAIL_MESSAGE);
            }
        } else {
            $user['email'] = strtolower($user['username']) . '@bogus.bogus';
        }
        Log::info('Creating user...');
        $created=user::create(array(
            'fullname' => $user['fullName'],
            'email' => strtolower($user['email']),
            'name' => $user['username'],
            'password' => static::USERDEFAULTPASSWORD,
            'isactive' => 0
        ))['created'];
        Log::info('...done');
        $created['receiversId']=$created['id'];
        Log::debug('Returning from UserManagement::createUser');
        return $created;
    }

    /**
     * @throws BadRequestException
     * @throws ForbiddenException
     * @throws ServerException
     * @throws NotFoundException
     */
    public static function activateUser(array $user): array {
        Log::debug('In UserManagement::activateUser');
        static::require('username', $user);
        session::becomeAdmin();
        $user=user::getByName($user['username']);
        if(!$user){ throw new NotFoundException(static::USER_NOT_FOUND); }
        user::update($user['id'], array('isactive'=>1));
        $user=user::getByName($user['name']);
        Log::info('Activated user '.$user['name']);
        Log::debug('Returning from UserManagement::activateUser');
        return $user;
    }

    /**
     * @throws BadRequestException
     * @throws ForbiddenException
     * @throws ServerException
     */
    public static function deactivateUser(array $user): array {
        Log::debug('In UserManagement::deactivateUser');
        static::require('username', $user);
        session::becomeAdmin();
        $user=user::getByName($user['username']);
        user::update($user['id'], array('isactive'=>0));
        $user=user::getByName($user['name']);
        Log::info('Deactivated user '.$user['name']);
        Log::debug('Returning from UserManagement::deactivateUser');
        return $user;
    }

}