package io.openex.rest.file;

import io.openex.database.model.Document;
import io.openex.database.model.Tag;
import io.openex.database.repository.DocumentRepository;
import io.openex.database.repository.TagRepository;
import io.openex.database.specification.DocumentSpecification;
import io.openex.rest.file.form.DocumentCreateInput;
import io.openex.rest.file.form.DocumentTagUpdateInput;
import io.openex.rest.file.form.DocumentUpdateInput;
import io.openex.rest.helper.RestBehavior;
import io.openex.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.transaction.Transactional;
import javax.validation.Valid;
import java.util.List;

@RestController
public class FileApi extends RestBehavior {

    private FileService fileService;
    private TagRepository tagRepository;
    private DocumentRepository documentRepository;

    @Autowired
    public void setTagRepository(TagRepository tagRepository) {
        this.tagRepository = tagRepository;
    }

    @Autowired
    public void setDocumentRepository(DocumentRepository documentRepository) {
        this.documentRepository = documentRepository;
    }

    @Autowired
    public void setFileService(FileService fileService) {
        this.fileService = fileService;
    }

    @Transactional
    @PostMapping("/api/documents")
    public Document uploadDocument(@Valid @RequestPart("input") DocumentCreateInput input,
                                   @RequestPart("file") MultipartFile file) throws Exception {
        fileService.uploadFile(file);
        Document document = new Document();
        document.setName(file.getOriginalFilename());
        document.setDescription(input.getDescription());
        document.setTags(fromIterable(tagRepository.findAllById(input.getTagIds())));
        document.setPath("minio");
        document.setType(file.getContentType());
        return documentRepository.save(document);
    }

    @GetMapping("/api/documents")
    public List<Document> documents() {
        Sort sorting = Sort.by(Sort.Direction.DESC, "id");
        return documentRepository.findAll(DocumentSpecification.onlyMinio(), sorting);
    }

    @GetMapping("/api/documents/{documentId}")
    public Document document(@PathVariable String documentId) {
        return documentRepository.findById(documentId).orElseThrow();
    }

    @GetMapping("/api/documents/{documentId}/tags")
    public List<Tag> documentTags(@PathVariable String documentId) {
        Document document = documentRepository.findById(documentId).orElseThrow();
        return document.getTags();
    }

    @PutMapping("/api/documents/{documentId}/tags")
    public Document documentTags(@PathVariable String documentId,
                                 @RequestBody DocumentTagUpdateInput input) {
        Document document = documentRepository.findById(documentId).orElseThrow();
        document.setTags(fromIterable(tagRepository.findAllById(input.getTagIds())));
        return documentRepository.save(document);
    }

    @PutMapping("/api/documents/{documentId}")
    public Document updateDocumentInformation(@PathVariable String documentId,
                                              @Valid @RequestBody DocumentUpdateInput input) {
        Document document = documentRepository.findById(documentId).orElseThrow();
        document.setUpdateAttributes(input);
        document.setTags(fromIterable(tagRepository.findAllById(input.getTagIds())));
        return documentRepository.save(document);
    }

    @DeleteMapping("/api/documents/{documentId}")
    public void deleteDocument(@PathVariable String documentId) {
        documentRepository.deleteById(documentId);
    }
}

@@ -625,16 +625,61 @@
 n.Sort;%0A
+import org.springframework.http.HttpHeaders;%0A
 import o
@@ -773,24 +773,71 @@
 ipartFile;%0A%0A
+import javax.servlet.http.HttpServletResponse;%0A
 import javax
@@ -895,16 +895,72 @@
 .Valid;%0A
+import java.io.IOException;%0Aimport java.io.InputStream;%0A
 import j
@@ -3802,24 +3802,666 @@
 nt);%0A    %7D%0A%0A
+    @GetMapping(%22/api/documents/%7BdocumentId%7D/file%22)%0A    public void downloadDocument(@PathVariable String documentId, HttpServletResponse response) throws IOException %7B%0A        Document document = documentRepository.findById(documentId).orElseThrow();%0A        response.addHeader(HttpHeaders.CONTENT_DISPOSITION, %22attachment; filename=%22 + document.getName());%0A        response.addHeader(HttpHeaders.CONTENT_TYPE, document.getType());%0A        response.setStatus(HttpServletResponse.SC_OK);%0A        InputStream fileStream = fileService.getFile(document.getName()).orElseThrow();%0A        fileStream.transferTo(response.getOutputStream());%0A    %7D%0A%0A
     @DeleteM

Add download document API