<?php
/**
 * Pterodactyl - Panel
 * Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
 *
 * This software is licensed under the terms of the MIT license.
 * https://opensource.org/licenses/MIT
 */

namespace Pterodactyl\Http\Requests\Server;

use GuzzleHttp\Exception\RequestException;
use Illuminate\Contracts\Config\Repository;
use Pterodactyl\Exceptions\Http\Server\FileSizeTooLargeException;
use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface;
use Pterodactyl\Exceptions\Http\Server\FileTypeNotEditableException;
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;

class UpdateFileContentsFormRequest extends ServerFormRequest
{
    /**
     * Return the permission string to validate this request aganist.
     *
     * @return string
     */
    protected function permission(): string
    {
        return 'edit-files';
    }

    /**
     * Authorize a request to edit a file.
     *
     * @return bool
     *
     * @throws \Pterodactyl\Exceptions\DisplayException
     * @throws \Pterodactyl\Exceptions\Http\Server\FileSizeTooLargeException
     * @throws \Pterodactyl\Exceptions\Http\Server\FileTypeNotEditableException
     * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
     */
    public function authorize()
    {
        if (! parent::authorize()) {
            return false;
        }

        $server = $this->attributes->get('server');
        $token = $this->attributes->get('server_token');

        return $this->checkFileCanBeEdited($server, $token);
    }

    /**
     * @return array
     */
    public function rules()
    {
        return [];
    }

    /**
     * Checks if a given file can be edited by a user on this server.
     *
     * @param \Pterodactyl\Models\Server $server
     * @param string                     $token
     * @return bool
     *
     * @throws \Pterodactyl\Exceptions\DisplayException
     * @throws \Pterodactyl\Exceptions\Http\Server\FileSizeTooLargeException
     * @throws \Pterodactyl\Exceptions\Http\Server\FileTypeNotEditableException
     * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
     */
    private function checkFileCanBeEdited($server, $token)
    {
        $config = app()->make(Repository::class);
        $repository = app()->make(FileRepositoryInterface::class);

        try {
            $stats = $repository->setNode($server->node_id)->setAccessServer($server->uuid)
                ->setAccessToken($token)
                ->getFileStat($this->route()->parameter('file'));
        } catch (RequestException $exception) {
            throw new DaemonConnectionException($exception);
        }

        if (! $stats->file || ! in_array($stats->mime, $config->get('pterodactyl.files.editable'))) {
            throw new FileTypeNotEditableException(trans('server.files.exceptions.invalid_mime'));
        }

        if ($stats->size > $config->get('pterodactyl.files.max_edit_size')) {
            throw new FileSizeTooLargeException(trans('server.files.exceptions.max_size'));
        }

        $this->attributes->set('file_stats', $stats);

        return true;
    }
}
