<?php


namespace CubiStore\Web\Controller;

use CubiStore\Web\Service\ApkService;
use CubiStore\Web\Service\AppService;
use CubiStore\Web\Utils\Apk;
use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\UploadedFileInterface;
use Slim\Psr7\Request;
use Slim\Psr7\Response;
use Twig\Environment;

class AppManager
{
    public function createShow(Environment $twig, ResponseInterface $response)
    {
        $response->getBody()->write($twig->render('app/create.html.twig'));
        return $response;
    }

    public function createAction(Request $request, Response $response, ApkService $apkService, AppService $appService, EntityManager $em)
    {
        $files = $request->getUploadedFiles();

        if (!isset($files['apk'])) {
            return $response
                ->withStatus(302)
                ->withHeader('Location', '/app/create');
        }

        /** @var UploadedFileInterface $apkUpload */
        $apkUpload = $files['apk'];

        // Check if upload succeeded
        if ($apkUpload->getError() !== UPLOAD_ERR_OK) {
            return $response
                ->withStatus(302)
                ->withHeader('Location', '/app/create');
        }

        $tmp = tempnam(sys_get_temp_dir(), 'apk-');

        if ($tmp === false) {
            throw new \RuntimeException("Failed creating temp file");
        }

        $apkUpload->moveTo($tmp);

        $apk = new Apk($tmp);

        if (!$apk->isValid()) {
            return $response
                ->withStatus(302)
                ->withHeader('Location', '/app/create');
        }

        if ($appService->hasApprovedApp($apk->getPackageName())) {
            return $response
                ->withStatus(302)
                ->withHeader('Location', '/app/create');
        }

        $app = $appService->createApp($apk);

        // Flush to get id, as it's used in getStorePath
        $em->persist($app);
        $em->flush();

        $storePath = $appService->getStorePath($app, $apk);
        if (!is_dir($storePath) && !mkdir($storePath, 0777, true)) {
            return $response
                ->withStatus(302)
                ->withHeader('Location', '/app/create');
        }

        $newApkPath = $storePath . '/' . $apkUpload->getClientFilename();
        if (!rename($tmp, $newApkPath)) {
            return $response
                ->withStatus(302)
                ->withHeader('Location', '/app/create');
        }

        $release = $appService->createRelease($apk, $app, $newApkPath);
        $em->persist($release);
        $em->flush();

        return $response
            ->withStatus(302)
            ->withHeader('Location', '/app/' . $app->getName() . '/' . $app->getId() . '/manage');
    }
}
