<?php

namespace WPIDE\App\Services\Auth;

class User implements \JsonSerializable
{
    protected $role = 'guest';

    protected $permissions = [];

    protected $username = '';

    protected $homedir = '';

    protected $name = '';

    protected $email = '';

    protected $avatar = '';

    protected $available_roles = ['guest', 'user', 'admin'];

    protected $available_permissions = ['read', 'write', 'upload', 'download', 'batchdownload', 'zip'];

    public function __construct()
    {
    }

    public function isGuest(): bool
    {
        return 'guest' == $this->role;
    }

    public function isUser(): bool
    {
        return 'user' == $this->role;
    }

    public function isAdmin(): bool
    {
        return 'admin' == $this->role;
    }

    public function hasRole($check): bool
    {
        if (is_array($check)) {
            return in_array($this->getRole(), $check);
        }

        return $this->getRole() == $check;
    }

    public function getRole(): string
    {
        return $this->role;
    }

    public function hasPermissions($check): bool
    {
        if (empty($check)) {
            return true;
        }

        if (is_array($check)) {
            return count(array_intersect($check, $this->getPermissions())) == count($check);
        }

        return in_array($check, $this->getPermissions());
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setEmail(string $email): void
    {
        $this->email = $email;
    }

    public function getEmail(): string
    {
        return $this->email;
    }

    public function setAvatar(string $avatar): void
    {
        $this->avatar = $avatar;
    }

    public function getAvatar(): string
    {
        return $this->avatar;
    }

    public function setUsername(string $username)
    {
        $this->username = $username;
    }

    public function getUsername(): string
    {
        return $this->username;
    }

    public function setHomedir(string $homedir)
    {
        $this->homedir = $homedir;
    }

    public function getHomeDir(): string
    {
        return $this->homedir;
    }

    public function setRole(string $role)
    {
        $this->checkValidRole($role);

        $this->role = $role;
    }

    /**
     * @throws \Exception
     */
    public function setPermissions($permissions, $encoded = false)
    {
        if ($encoded) {
            $permissions = explode('|', $permissions);
        }

        $this->checkValidPermissions($permissions);

        $this->permissions = $permissions;
    }

    public function getPermissions($encoded = false)
    {
        return $encoded ? implode('|', $this->permissions) : $this->permissions;
    }

    public function jsonSerialize(): array
    {
        return [
            'role' => $this->getRole(),
            'permissions' => $this->getPermissions(),
            'homedir' => $this->getHomeDir(),
            'username' => $this->getUsername(),
            'name' => $this->getName(),
            'email' => $this->getEmail(),
            'avatar' => $this->getAvatar(),
        ];
    }

    protected function checkValidRole($role)
    {
        if (! in_array($role, $this->available_roles)) {
            throw new \Exception("User role {$role} does not exists.");
        }

        return true;
    }

    protected function checkValidPermissions(array $permissions)
    {
        foreach ($permissions as $permission) {
            if ($permission && ! in_array($permission, $this->available_permissions)) {
                throw new \Exception("Permission {$permission} does not exists.");
            }
        }

        return true;
    }
}
