package com.fanruan.api.util;

import com.fr.general.CommonIOUtils;
import com.fr.general.IOUtils;

import javax.swing.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.channels.Channel;
import java.nio.charset.Charset;

/**
 * @author richie
 * @version 10.0
 * Created by richie on 2019-08-16
 */
public class IOKit {

    /**
     * 重命名指定的文件为另外一个文件.(不抛异常)
     * 用的native方法, 同一盘符的rename要比copy快
     * 因为用的系统API, 有可能在一定情况下rename失败,
     * 此时会去直接copy文件, 如果再失败就返回false.
     *
     * @param oldFile 原文件
     * @param newFile 命名后的新文件
     * @return 重命名成功则返回true,否则返回false
     */
    public static boolean renameTo(File oldFile, File newFile) {
        return CommonIOUtils.renameTo(oldFile, newFile);
    }

    /**
     * 将某个目录文件夹下的所有文件复制到另一文件夹下
     *
     * @param sourceDir 源文件夹
     * @param targetDir 目标路径(应该也是文件夹)
     * @throws IOException IO异常
     */
    public static void copyFilesInDirByPath(String sourceDir, String targetDir) throws IOException {
        CommonIOUtils.copyFilesInDirByPath(sourceDir, targetDir);
    }

    /**
     * 拷贝文件到某目录下
     *
     * @param src 源文件
     * @param dir 目标文件
     */
    public static void copy(File src, File dir) throws IOException {
        CommonIOUtils.copy(src, dir);
    }

    /**
     * 拷贝InputStream到dir目录下以fileName作为文件名的文件存在
     *
     * @param in       源文件
     * @param fileName 文件名
     * @param dir      目标文件
     */
    public static void copy(InputStream in, String fileName, File dir)
            throws IOException {
        CommonIOUtils.copy(in, fileName, dir);
    }

    /**
     * 覆盖文件内容
     */
    public static void cover(File src, File des) {
        CommonIOUtils.cover(src, des);
    }

    /**
     * 将输入流中的二进制文件拷贝到输出流中
     *
     * @param input  输入流
     * @param output 输出流
     * @throws IOException 拷贝过程中出现IO错误则抛出此异常
     */
    public static void copyBinaryTo(InputStream input, OutputStream output)
            throws IOException {
        CommonIOUtils.copyBinaryTo(input, output);
    }

    /**
     * 从输入流中按UTF-8编码读取字符串
     *
     * @param is 输入流
     * @return 读取出来的字符串
     * @throws UnsupportedEncodingException 编码类型不支持则抛出此异常
     */
    public static String inputStream2String(InputStream is)
            throws UnsupportedEncodingException {
        return CommonIOUtils.inputStream2String(is);
    }

    /**
     * 从输入流中按指定的编码读取字符串
     *
     * @param is      输入流
     * @param charset 读取字符串的编码方式
     * @return 读取出来的字符串
     * @throws UnsupportedEncodingException 编码类型不支持则抛出此异常
     */
    public static String inputStream2String(InputStream is, Charset charset)
            throws UnsupportedEncodingException {
        return CommonIOUtils.inputStream2String(is, charset.toString());
    }

    /**
     * 将输入流转为byte数组
     * <p/>
     * 原来的写法是 byte[] b = new byte[in.avalable]; in.read(b);
     * 但是在CipherInputStream测试的时候,发现拿到的byte[]长度为0
     *
     * @param in 输入流
     * @return byte数组
     */
    public static byte[] inputStream2Bytes(InputStream in) {
        return CommonIOUtils.inputStream2Bytes(in);
    }

    /**
     * 将字符从读取器中拷贝到写入器中
     *
     * @param reader 读取器
     * @param writer 写入器
     * @throws IOException 拷贝过程中发现IO错误则抛出此异常
     */
    public static void copyCharTo(Reader reader, Writer writer)
            throws IOException {
        CommonIOUtils.copyCharTo(reader, writer);
    }

    /**
     * 直接从磁盘中读取图片,这种方法效率稍低但每次图片更改了也能即时反应出来
     *
     * @param resource 图片的路径
     * @return 图片
     */
    public static BufferedImage readImage(String resource) {
        return IOUtils.readImage(resource);
    }

    /**
     * 读取图标,该方法启用了缓存
     *
     * @param resource 图标文件的存放路径
     * @return 图标
     */
    public static Icon readIcon(String resource) {
        return IOUtils.readIcon(resource);
    }

    /**
     * 从输入流中读取图片
     *
     * @param input 输入流
     * @return 图片
     * @throws IOException 读取图片的过程中发现IO错误则抛出此异常
     */
    public static BufferedImage readImage(InputStream input) throws IOException {
        return CommonIOUtils.readImage(input);
    }

    /**
     * 读取资源
     *
     * @param path 资源存放的路径,可以是一个URL
     * @return 返回资源的输入流
     */
    public static InputStream readResource(String path) {
        return IOUtils.readResource(path);
    }

    /**
     * 把指定位置的资源以默认的UTF-8编码的形式读取成字符串
     *
     * @param path 资源存放的路径
     * @return 表示资源内容的字符串
     */
    public static String readResourceAsString(String path) {
        return IOUtils.readResourceAsString(path);
    }

    /**
     * 将指定位置的资源以指定的编码形式读取成字符串
     *
     * @param path   资源存放的路径
     * @param encode 读取资源所用的编码
     * @return 表示资源内容的字符串
     */
    public static String readResourceAsString(String path, Charset encode) {
        return IOUtils.readResourceAsString(path, encode.toString());
    }

    /**
     * 关闭通道
     * @param device 通道
     */
    public static void close(Channel device) {
        CommonIOUtils.close(device);
    }

    /**
     * 关闭输出流
     * @param stream 输出流
     */
    public static void close(OutputStream stream) {
        CommonIOUtils.close(stream);
    }

    /**
     * 关闭输入流
     * @param stream 输入流
     */
    public static void close(InputStream stream) {
        CommonIOUtils.close(stream);
    }
}