<?php


namespace App\Model\Facades\Writers;


use App\Model\Entities\Game;
use App\Model\Facades\Readers\GameReader;
use App\Model\Facades\Readers\PlatformReader;
use App\Model\Facades\Readers\PublisherReader;
use App\Model\Facades\Readers\StudioReader;
use App\Model\Services\GameService;
use Throwable;

class GameWriter extends BaseWriter
{
    /** @var GameService */
    protected $gameService;
    /** @var PublisherReader */
    protected $publisherReader;
    /** @var PlatformReader */
    protected $platformReader;
    /** @var StudioReader */
    protected $studioReader;
    /** @var GameReader */
    protected $gameReader;
    /** @var  SiteWriter */
    protected $siteWriter;

    public function inject(GameService $gameService,
                           PublisherReader $publisherReader,
                           PlatformReader $platformReader,
                           StudioReader $studioReader,
                           GameReader $gameReader,
                           SiteWriter $siteWriter)
    {
        $this->gameService = $gameService;
        $this->publisherReader = $publisherReader;
        $this->platformReader = $platformReader;
        $this->studioReader = $studioReader;
        $this->gameReader = $gameReader;
        $this->siteWriter = $siteWriter;
    }

    /**
     * @param string $name
     * @param $publisher
     * @param $studio
     * @param $version
     * @return Game
     * @throws Throwable
     */
    public function createMmoGame(string $name, $publisher, $studio, $version) : Game
    {
        $publisherEntity = $this->publisherReader->validatePublisher($publisher);
        $studioEntity = $this->studioReader->validateStudio($studio);
        try {
            $this->beginTransaction();
            $gameData = $this->gameService->createMmoGameData($publisherEntity, $studioEntity, $version);
            $game = $this->siteWriter->createGame($gameData, $name);
            $this->commit();
        } catch (Throwable $e) {
            $this->rollback();
            throw $e;
        }

        return $game;
    }

    public function editName($game, string $newName)
    {
        $gameEntity = $this->gameReader->validateGame($game);

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

    public function editState($game, string $newState)
    {
        $gameEntity = $this->gameReader->validateGame($game);

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