package com.izouma.nineth.service.storage;

import com.izouma.nineth.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;

@Service
@Slf4j
@ConditionalOnProperty(name = "storage.provider", havingValue = "local")
public class LocalStorageService implements StorageService {

    @Value("${storage.local_path}")
    private String localPath;

    @Override
    public String uploadFromInputStream(InputStream fin, String path) {
        log.info("本地上传: inputStream -> {}", path);
        try {
            return upload(fin, path);
        } catch (IOException e) {
            log.error("本地上传失败", e);
            throw new BusinessException("上传失败", e.getMessage());
        }
    }

    @Override
    public String uploadFromUrl(String url, String path) {
        log.info("本地上传: {} -> {}", url, path);
        try {
            InputStream inputStream = new URL(url).openStream();
            return upload(inputStream, path);
        } catch (Exception e) {
            log.error("本地上传失败", e);
            throw new BusinessException("上传失败", e.getMessage());
        }
    }

    private String upload(InputStream inputStream, String path) throws IOException {
        Path uploadPath = Paths.get(localPath, path).getParent();
        if (Files.notExists(uploadPath, LinkOption.values())) {
            Files.createDirectories(uploadPath);
        }
        FileUtils.copyToFile(inputStream, new File(Paths.get(localPath, path).toString()));
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "files" + "/" + path;
    }
}
