<?php
/**
 * Copyright (c) 2016 Serhii Borodai <clarifying@gmail.com>.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 *
 */

namespace App\Action;


use App\Authentication\UserService;
use App\Entity\Download\Counter;
use App\Entity\Site as SiteEntity;
use App\Entity\User;
use App\Model\Sites;
use App\Model\Users;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response\HtmlResponse;
use Zend\Diactoros\Stream;


/**
 * Class DownloadCounter
 * @package App\Action
 */
class DownloadCounter extends Common
{

    /**
     * @param ServerRequestInterface $request
     * @param ResponseInterface $response
     * @param callable|null $next
     * @return mixed
     * @throws \Exception
     */
    function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
    {
        $this->initInfo($request);

        $siteId = $request->getAttribute('siteId');
        $domain = null;
        if ($siteId) {
            /** @var Sites $sitesModel */
            $sitesModel = $this->container->get(Sites::class);
            /** @var UserService $auth */
            $auth = $this->container->get(UserService::class);
            /** @var SiteEntity $site */
            $site = $sitesModel->findByIdAndUserId($siteId, $auth->getIdentity()->getId());
            if ($site) {
                $domain = $site->getDomain();
            } else {
                throw new \Exception(_t('No such site for user'));
            }
        }

        return $this->downloadFile($response, $domain);
    }

    /**
     * @param $response ResponseInterface
     * @return mixed
     * @throws \Exception
     */
    protected function downloadFile($response, $domain = null)
    {
        /** @var UserService $userAuth */
        $userAuth = $this->container->get(UserService::class);
        /** @var Users $userModel */
        $userModel = $this->container->get(Users::class);
        /** @var User $user */
        $user = $userModel->findById($userAuth->getIdentity()->getId());

        $manualContent = $this->template->render('download::manual', [
            'username' => $user->getFullname(),
            'uuid' => $user->getUuid(),
            'domain' => $domain,
            'layout' => 'empty'
        ]);

        $scriptContent = $this->template->render('download::counter-script', [
            'username' => $user->getFullname(),
            'uuid' => $user->getUuid(),
            'domain' => $domain,
            'layout' => 'empty',
        ]);

        $compressingCounterConfig = $this->container->get('config')[Counter::class];

        /** @var \ZipArchive $zip */
        $zip = $this->container->get('archiver');

        $archive = $compressingCounterConfig[Counter::STORE_DIR] . 'manual-' . $user->getUuid() . '.zip';
        if (!realpath($archive)) {
            if (true !== $errcode = $zip->open($archive, \ZipArchive::CREATE)) {
                throw new \Exception('Compressing error', $errcode);
            }

            $zip->addFromString($compressingCounterConfig[Counter::FILE_MANUAL], $manualContent);
            $zip->addFromString($compressingCounterConfig[Counter::FILE_SCRIPT], $scriptContent);

            $zip->close();
        }
        $tmpStream = fopen($archive, 'r');

        $stream = new Stream($tmpStream);
        return $response
            // (new \finfo(FILEINFO_MIME))->buffer($body)
            ->withHeader('Content-Type', 'application/octet-stream')
            ->withHeader('Content-Disposition', 'attachment; filename=manual-' . $user->getUuid() . '.zip')
            ->withHeader('Content-Transfer-Encoding', 'Binary')
            ->withHeader('Content-Description', 'File Transfer')
            ->withHeader('Pragma', 'public')
            ->withHeader('Expires', '0')
            ->withHeader('Cache-Control', 'must-revalidate')
            ->withBody($stream)
            ->withHeader('Content-Length', "{$stream->getSize()}");

    }
}