package ru.ulstu.file.service;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import ru.ulstu.file.model.FileData;
import ru.ulstu.file.repostory.FileRepository;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;

import static java.nio.charset.StandardCharsets.UTF_8;

@Service
public class FileService {
    private final static int META_FILE_NAME_INDEX = 0;
    private final static int META_FILE_SIZE_INDEX = 1;

    private String tmpDir;
    private FileRepository fileRepository;

    public FileService(FileRepository fileRepository) {
        tmpDir = System.getProperty("java.io.tmpdir");
        this.fileRepository = fileRepository;
    }

    public FileData createFileFromTmp(String tmpFileName) throws IOException {
        FileData fileData = new FileData();
        fileData.setData(getTmpFile(tmpFileName));
        fileData.setName(getTmpFileName(tmpFileName));
        fileData.setCreateDate(new Date());
        return fileRepository.save(fileData);
    }

    public String uploadToTmpDir(MultipartFile multipartFile) throws IOException {
        String tmpFileName = String.valueOf(System.currentTimeMillis());
        Files.write(getTmpFilePath(tmpFileName), multipartFile.getBytes());
        String meta = multipartFile.getOriginalFilename() + "\n" + multipartFile.getSize();
        Files.write(getTmpFileMetaPath(tmpFileName), meta.getBytes(UTF_8));
        return tmpFileName;
    }

    private String[] getMeta(String tmpFileName) throws IOException {
        return new String(Files.readAllBytes(getTmpFileMetaPath(tmpFileName)), UTF_8)
                .split("\n");
    }

    public long getTmpFileSize(String tmpFileName) throws IOException {
        return Long.valueOf(getMeta(tmpFileName)[META_FILE_SIZE_INDEX]).longValue();
    }

    public String getTmpFileName(String tmpFileName) throws IOException {
        return getMeta(tmpFileName)[META_FILE_NAME_INDEX];
    }

    public byte[] getTmpFile(String tmpFileName) throws IOException {
        return Files.readAllBytes(getTmpFilePath(tmpFileName));
    }

    public FileData getFile(Integer fileId) {
        return fileRepository.findOne(fileId);
    }

    public void deleteTmpFile(String tmpFileName) throws IOException {
        Files.delete(getTmpFilePath(tmpFileName));
    }

    private Path getTmpFilePath(String tmpFileName) {
        return Paths.get(tmpDir, tmpFileName);
    }

    private Path getTmpFileMetaPath(String tmpFileName) {
        return Paths.get(getTmpFilePath(tmpFileName) + ".meta");
    }

    public void deleteFile(FileData fileData) {
        fileRepository.delete(fileData);
    }
}
