<?php
namespace IntellexApps\PHP\UploadFile\Controller;

use IntellexApps\PHP\UploadFile\Domain\Model\FolderItem;
use IntellexApps\PHP\UploadFile\Domain\Request\File\CopyRequest;
use IntellexApps\PHP\UploadFile\Domain\Request\File\CreateRequest;
use IntellexApps\PHP\UploadFile\Domain\Request\File\DeleteRequest;
use IntellexApps\PHP\UploadFile\Domain\Request\File\ListFilesRequest;
use IntellexApps\PHP\UploadFile\Domain\Request\File\MoveRequest;
use IntellexApps\PHP\UploadFile\Domain\Request\File\RenameRequest;
use IntellexApps\PHP\UploadFile\Domain\Request\File\UpdatePermissionsRequest;
use IntellexApps\PHP\UploadFile\Domain\Request\File\UploadRequest;
use IntellexApps\PHP\UploadFile\Domain\Request\File\ViewItemRequest;
use IntellexApps\PHP\UploadFile\Domain\Service\PermissionService;
use IntellexApps\PHP\UploadFile\Domain\Service\UploadFileService;
use IntellexApps\PHP\UploadFile\Network\FileNotFoundResponse;
use IntellexApps\PHP\UploadFile\Util\Controller;
use Swagger\Annotations as SWG;

/**
 * @SWG\Swagger(
 *     schemes={"http"},
 *     host="asset.dev",
 *     basePath="/api/v1/",
 *     consumes={"application/json"},
 *     produces={"application/json"},
 *     @SWG\Info(
 *         version="0.0.1",
 *         title="FileUpload",
 *         description="This is API documentation for UploadFile plugin made by Intellex",
 *         termsOfService="",
 *         @SWG\Contact(
 *             email="boban@intellex.rs"
 *         ),
 *         @SWG\License(
 *             name="Apache 2.0",
 *             url="http://www.apache.org/licenses/LICENSE-2.0.html"
 *         )
 *     ),
 *     @SWG\ExternalDocumentation(
 *         description="Find out more about UploadFile",
 *         url="https://www.intellex.rs"
 *     )
 * )
 */
class FileController extends Controller
{

    /** @var UploadFileService */
    var $uploadFileService;

    /** @var  PermissionService */
    var $permissionsService;

    /**
     * Initialize controller
     */
    protected function init()
    {
        $this->uploadFileService = $this->container->get('upload');
        $this->permissionsService = $this->container->get('permission');
    }

    /**
     * List files
     *
     * @SWG\Post(
     *     path="/list",
     *     description="List files in supplied path",
     *     @SWG\Parameter(
     *         in="body",
     *         required=true,
     *         @SWG\Schema(ref="#/definitions/ListFilesRequest")
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="Folder items",
     *         @SWG\Schema(ref="#/definitions/FolderItems")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function listFilesAction()
    {
        return $this->uploadFileService->listFiles(
            new ListFilesRequest($this->request)
        );
    }

    /**
     * Upload a file
     *
     * @return FolderItem

     * @SWG\Post(
     *     path="/upload",
     *     description="Upload a file",
     *     @SWG\Parameter(
     *         in="body",
     *         required=true,
     *         @SWG\Schema(ref="#/definitions/UploadFileRequest")
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="successful response",
     *         @SWG\Schema(ref="#/definitions/FolderItem")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function uploadAction()
    {
        return $this->uploadFileService->upload(
            new UploadRequest($this->request)
        );
    }

    /**
     * Move action

     * @SWG\Post(
     *     path="/move",
     *     description="Move a file",
     *     @SWG\Parameter(
     *         in="body",
     *         required=true,
     *         @SWG\Schema(ref="#/definitions/MoveRequest")
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="successful response",
     *         @SWG\Schema(ref="#/definitions/FolderItem")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function moveAction()
    {
        return $this->uploadFileService->move(
            new MoveRequest($this->request)
        );
    }

    /**
     * Copy action

     * @SWG\Post(
     *     path="/copy",
     *     description="Copy a file",
     *     @SWG\Parameter(
     *         in="body",
     *         required=true,
     *         @SWG\Schema(ref="#/definitions/CopyRequest")
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="successful response",
     *         @SWG\Schema(ref="#/definitions/FolderItem")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function copyAction()
    {
        return $this->uploadFileService->copy(
            new CopyRequest($this->request)
        );
    }

    /**
     * Create action

     * @SWG\Post(
     *     path="/create",
     *     description="Create a directory",
     *     @SWG\Parameter(
     *         in="body",
     *         required=true,
     *         @SWG\Schema(ref="#/definitions/CreateRequest")
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="successful response",
     *         @SWG\Schema(ref="#/definitions/FolderItem")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function createAction()
    {
        return $this->uploadFileService->create(
            new CreateRequest($this->request)
        );
    }

    /**
     * Overwrite action

     * @SWG\Post(
     *     path="/overwrite",
     *     description="Overwrite a file",
     *     @SWG\Parameter(
     *         in="body",
     *         required=true,
     *         @SWG\Schema(ref="#/definitions/UploadFileRequest")
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="successful response",
     *         @SWG\Schema(ref="#/definitions/FolderItem")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function overwriteAction()
    {
        return $this->uploadFileService->upload(
            new UploadRequest($this->request),
            true
        );
    }

    /**
     * Delete action
     *
     * @SWG\Post(
     *     path="/delete",
     *     description="Delete a file",
     *     @SWG\Parameter(
     *         in="body",
     *         required=true,
     *         @SWG\Schema(ref="#/definitions/DeleteRequest")
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="successful response",
     *         @SWG\Schema(ref="#/definitions/DeleteResponse")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function deleteAction()
    {
        return $this->uploadFileService->delete(
            new DeleteRequest($this->request),
            true
        );
    }

    /**
     * Rename folder or item

     * @SWG\Post(
     *     path="/rename",
     *     description="Rename a file or folder",
     *     @SWG\Parameter(
     *         in="body",
     *         required=true,
     *         @SWG\Schema(ref="#/definitions/RenameRequest")
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="successful response",
     *         @SWG\Schema(ref="#/definitions/FolderItem")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function renameAction()
    {
        return $this->uploadFileService->rename(
            new RenameRequest($this->request)
        );
    }

    /**
     * View action

     * @SWG\Post(
     *     path="/view",
     *     description="View file or folder details",
     *     @SWG\Parameter(
     *         in="body",
     *         required=true,
     *         @SWG\Schema(ref="#/definitions/ViewRequest")
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="successful response",
     *         @SWG\Schema(ref="#/definitions/FolderItem")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function viewAction()
    {
        return $this->uploadFileService->view(
            new ViewItemRequest($this->request)
        );
    }

    /**
     * Download action

     * @SWG\Post(
     *     path="/download",
     *     description="View file or folder details",
     *     @SWG\Response(
     *         response=200,
     *         description="successful response",
     *         @SWG\Schema(ref="#/definitions/FolderItem")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function downloadAction()
    {
        try {
            return $this->uploadFileService->outputFile($this->request->data['file']);
        } catch(\Exception $e) {
            return new FileNotFoundResponse();
        }
    }

    /**
     * Update permissions action
     *
     * @SWG\Post(
     *     path="/permissions/update",
     *     description="Updates permissions for file/folder",
     *     @SWG\Response(
     *         response=200,
     *         description="successful response",
     *         @SWG\Schema(ref="#/definitions/FolderItem")
     *     ),
     *     @SWG\Response(
     *         response="default",
     *         description="unexpected error",
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
     *     )
     * )
     */
    public function updatePermissionsAction()
    {
        return $this->permissionsService->updateFilePermissions(
            new UpdatePermissionsRequest($this->request)
        );
    }
}