<?php


namespace App\Model\Facades\Writers;


use App\Model\Entities\GameData\Mmorpg\Region;
use App\Model\Entities\GameData\Mmorpg\Server;
use App\Model\Facades\Readers\RegionReader;
use App\Model\Facades\Readers\ServerReader;
use App\Model\Services\ServerService;
use Throwable;

class ServerWriter extends BaseWriter
{
    /** @var  ServerReader */
    protected $serverReader;
    /** @var  ServerService */
    protected $serverService;
    /** @var  RegionReader */
    protected $regionReader;

    public function inject(ServerService $serverService, RegionReader $regionReader, ServerReader $serverReader)
    {
        $this->serverService = $serverService;
        $this->regionReader = $regionReader;
        $this->serverReader = $serverReader;
    }

    /**
     * @param int|Region $region
     * @param string $name
     * @return Server
     * @throws Throwable
     */
    public function createServer($region, string $name) : Server
    {
        $regionEntity = $this->regionReader->validateRegion($region);

        try {
            $this->beginTransaction();
            $server = $this->serverService->createServer($this->getLoggedInUser(), $regionEntity, $name);
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $server;
    }

    public function editState($id, $newState)
    {
        $serverEntity = $this->serverReader->validateServer($id);

        try {
            $this->beginTransaction();
            $serverEntity->setState($newState);
            $serverEntity->setEditedBy($this->getLoggedInUser());
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }
    }

    public function editName($id, $newName)
    {
        $serverEntity = $this->serverReader->validateServer($id);

        try {
            $this->beginTransaction();
            $serverEntity->setName($newName);
            $serverEntity->setEditedBy($this->getLoggedInUser());
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }
    }
}