package eu.eudat.logic.services.helpers;

import eu.eudat.exceptions.files.TempFileNotFoundException;
import eu.eudat.models.data.files.ContentFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

/**
 * Created by ikalyvas on 3/15/2018.
 */
@Service("fileStorageService")
public class FileStorageServiceImpl implements FileStorageService {
    private static final Logger logger = LoggerFactory.getLogger(FileStorageServiceImpl.class);

    private Environment environment;

    @Autowired
    public FileStorageServiceImpl(Environment environment) {
        this.environment = environment;
        this.init();
    }

    public List<ContentFile> writeToTempFileSystem(MultipartFile[] multipartFiles) throws IOException {
        List<ContentFile> contentFileList = new LinkedList<>();
        for (MultipartFile multipartFile : Arrays.asList(multipartFiles)) {
            UUID id = UUID.randomUUID();
            Files.copy(multipartFile.getInputStream(), Paths.get(environment.getProperty("files.storage.temp")).resolve(id.toString()));
            ContentFile contentFile = new ContentFile(multipartFile.getOriginalFilename(), id, "temp", getFileExtension(multipartFile.getOriginalFilename()));
            contentFileList.add(contentFile);
        }
        return contentFileList;
    }

    public ContentFile copyFromTempFileSystem(ContentFile file) throws IOException, TempFileNotFoundException {
        UUID id = UUID.randomUUID();
        if (!Files.exists(Paths.get(environment.getProperty("files.storage.temp") + "/" + file.getId())))
            throw new TempFileNotFoundException();
        Files.copy(Paths.get(environment.getProperty("files.storage.temp") + "/" + file.getId()), Paths.get(environment.getProperty("files.storage.final")).resolve(id.toString()));
        ContentFile contentFile = new ContentFile(file.getFilename(), id, file.getLocation(), file.getType());
        return contentFile;
    }

    public Resource readFromFilesystem(String filename, String type, String location) throws IOException {
        if (location.equals("temp")) {
            return new UrlResource(Paths.get(environment.getProperty("files.storage.temp") + '/' + filename).toUri());
        } else {
            return new UrlResource(Paths.get(environment.getProperty("files.storage.final") + '/' + filename).toUri());
        }
    }

    public void init() {
        try {
            if (!Files.exists(Paths.get(environment.getProperty("files.storage.temp")))) {
                Files.createDirectory(Paths.get(environment.getProperty("files.storage.temp")));
            }
            if (!Files.exists(Paths.get(environment.getProperty("files.storage.final")))) {
                Files.createDirectory(Paths.get(environment.getProperty("files.storage.final")));
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
    }

    private static String getFileExtension(String fileName) {
        if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0)
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        else return "";
    }
}
