<?php
/* * ********************************************************************
*  ProxmoxVPS Product developed. (27.03.19)
* *
*
*  CREATED BY MODULESGARDEN       ->       http://modulesgarden.com
*  CONTACT                        ->       contact@modulesgarden.com
*
*
* This software is furnished under a license and may be used and copied
* only  in  accordance  with  the  terms  of such  license and with the
* inclusion of the above copyright notice.  This software  or any other
* copies thereof may not be provided or otherwise made available to any
* other person.  No title to and  ownership of the  software is  hereby
* transferred.
*
*
* ******************************************************************** */

namespace ModulesGarden\ProxmoxAddon\App\Services\Vps;

use Illuminate\Database\Capsule\Manager as DB;
use MGProvision\Proxmox\v2 as proxmox;
use ModulesGarden\ProxmoxAddon\App\Models\User;
use ModulesGarden\ProxmoxAddon\App\Repositories\Vps\ProductConfigurationRepository;
use ModulesGarden\ProxmoxAddon\App\Services\Utility;
use ModulesGarden\ProxmoxAddon\Core\Traits\Smarty;
use ModulesGarden\ProxmoxAddon\App\Enum\Vps\CustomField;

/**
 * Trait UserService
 * @package ModulesGarden\Servers\ProxmoxVps\App\Services
 * @method ProductConfigurationRepository configuration()
 */
trait UserService
{
    use Smarty;

    /**
     * @return User
     */
    protected function getUser()
    {
        $userId    = $this->getWhmcsParamByKey('userid');
        $serviceId = $this->getWhmcsParamByKey('serviceid');
        if (User::ofUserId($userId)->ofHostingId($serviceId)->count())
        {
            return User::ofUserId($userId)->ofHostingId($serviceId)->orderBy("id", "desc")->firstOrFail();
        } else if(User::ofUserId($userId)->ofHostingId('0')->count()){
            return User::ofUserId($userId)->ofHostingId('0')->orderBy("id", "desc")->firstOrFail();
        }
        $hostingId = $this->configuration()->isOneUserPerVps() ? $serviceId : '0';
        return User::ofUserId($userId)->ofHostingId($hostingId)->orderBy("id", "desc")->firstOrFail();
    }

    protected function isUser()
    {
        $userId    = $this->getWhmcsParamByKey('userid');
        $serviceId = $this->getWhmcsParamByKey('serviceid');
        if (User::ofUserId($userId)->ofHostingId($serviceId)->count())
        {
            return true;
        }
        else if(User::ofUserId($userId)->ofHostingId('0')->count()){
            return true;
        }
        $hostingId = $this->configuration()->isOneUserPerVps() ? $serviceId : '0';
        return User::ofUserId($userId)->ofHostingId($hostingId)->count() == 1;
    }

    /**
     * @return User
     * @throws proxmox\v2\ProxmoxApiException
     */
    public function userCreate(User $user = null)
    {

        if (is_null($user))
        {
            $user          = new User();
            $user->user_id = $this->getWhmcsParamByKey('userid');
        }
        $userPrefix = $this->configuration()->getUserPrefix();
        if ($userPrefix)
        {
            $userPrefix = $this->getSmarty()->fetchString($userPrefix, [
                "serviceid"  => $this->getWhmcsParamByKey('serviceid'),
                "service_id" => $this->getWhmcsParamByKey('serviceid')
            ]);
        }
        if ($this->configuration()->isOneUserPerVps())
        {
            $user->hosting_id = $this->getWhmcsParamByKey('serviceid');
        }
        else
        {
            $user->hosting_id = '0';
        }
        $username = $this->getWhmcsCustomField(CustomField::USERNAME) ? $this->getWhmcsCustomField(CustomField::USERNAME) : $this->getWhmcsParamByKey('username');
        $user->username = $userPrefix .  $username;
        $user->setPassword(Utility::generatePassword(12));
        $user->realm = $this->configuration()->getRealm();
        $userService = new proxmox\models\User();
        $userService->setApi($this->api());
        $data = [
            "userid"    => "{$user->username}@{$user->realm}",
            "comment"   => $this->configuration()->getUserComment(),
            "email"     => $this->getWhmcsParamByKey('clientsdetails')['email'],
            "enable"    => 1,
            "firstname" => $this->getWhmcsParamByKey('clientsdetails')['firstname'],
            "lastname"  => $this->getWhmcsParamByKey('clientsdetails')['lastname'],
            "password" => $user->getPassword()
        ];
        $userService->create($data);
        $userService->changePassword($user->getPassword());
        $user->save();
        return $user;
    }

    protected function userUpdate()
    {
        $user        = $this->getUser();
        $userService = new proxmox\models\User("{$user->username}@{$user->realm}");
        $userService->setApi($this->api());
        try
        {
            $userService->changePassword($user->getPassword());
        }
        catch (\Exception $ex)
        {
            if (!preg_match('/No such user/', $ex->getMessage()))
            {
                throw $ex;
            }
            $this->userCreate($user);
        }
        $vmid = $this->getWhmcsCustomField(CustomField::VMID);
        if (!$vmid)
        {
            return;
        }
        $permissions = $userService->permissions();
        foreach ($permissions as $p)
        {
            if ($p['path'] == "/vms/" . $vmid && $p['ugid'] == $userService->getUserid())
            {
                $userService->updatePermission($vmid, $p['roleid'], 1);
            }
        }
        $role = $this->configuration()->getUserRole();
        $userService->updatePermission($vmid, $role);
        return $this;
    }

    protected function deleteUser()
    {
        $user        = $this->getUser();
        $userService = new proxmox\models\User("{$user->username}@{$user->realm}");
        $userService->setApi($this->api());
        if (!$this->configuration()->isOneUserPerVps())
        {
            $h     = 'tblhosting';
            $p     = 'tblproducts';
            $query = DB::table($h)
                ->rightJoin($p, "{$p}.id", "=", "{$h}.packageid")
                ->where("{$h}.userid", $this->getWhmcsParamByKey('userid'))
                ->where("{$h}.id", "!=", $this->getWhmcsParamByKey('serviceid'))
                ->whereIn("{$h}.domainstatus", ['Active', 'Suspended'])
                ->where("{$p}.servertype", 'proxmoxVPS');
            if ($query->count() == "0")
            {
                $userService->delete();
                $user->delete();
                return $this;
            }
            $vmid = $this->getWhmcsParamByKey('customfields')['vmid'];
            if (!$vmid)
            {
                return $this;
            }
            //Delete permissions
            $permissions = $userService->permissions();
            foreach ($permissions as $p)
            {
                if ($p['path'] == "/vms/" . $vmid && $p['ugid'] == $userService->getUserid())
                {
                    $userService->updatePermission($vmid, $p['roleid'], 1);
                }
            }
        }
        else
        {
            $userService->delete();
            $user->delete();
            return $this;
        }
    }

    public function createUserIfNotExist(User $user){
        $userService = new proxmox\models\User();
        $userService->setApi($this->api());
        $userService->setUserid("{$user->username}@{$user->realm}");
        if(!$userService->exist()){
            $data = [
                "userid"    => "{$user->username}@{$user->realm}",
                "comment"   => $this->configuration()->getUserComment(),
                "email"     => $this->getWhmcsParamByKey('clientsdetails')['email'],
                "enable"    => 1,
                "firstname" => $this->getWhmcsParamByKey('clientsdetails')['firstname'],
                "lastname"  => $this->getWhmcsParamByKey('clientsdetails')['lastname'],
                "password" => $user->getPassword()
            ];
            $userService->create($data);
        }
        return $this;

    }

}