import * as fs from 'fs';
import * as path from 'path';
import * as crypto from 'crypto';

export default class FileHandle {
    /**
     * 获取参数指定文件的MD5码
     * @param filePath 文件路径
     * @returns 文件的 MD5 码
     */
    public static async GetFileMD5(filePath: string): Promise<string> {
        return new Promise((resolve, reject) => {
            fs.stat(filePath, (err, stats) => {
                if (err || !stats.isFile()) {
                    resolve('');
                    return;
                }
                const hash = crypto.createHash('md5');
                const stream = fs.createReadStream(filePath);
                stream.on('data', (data) => hash.update(data));
                stream.on('end', () => {
                    const md5 = hash.digest('hex');
                    resolve(md5);
                });
                stream.on('error', (error) => {
                    reject(error);
                });
            });
        });
    }

    /**
     * 获取参数指定文件的字节数组
     * @param filePath 文件路径
     * @returns 文件的字节数组
     */
    public static async GetBytes(filePath: string): Promise<Buffer | null> {
        return new Promise((resolve, reject) => {
            fs.stat(filePath, (err, stats) => {
                if (err || !stats.isFile()) {
                    resolve(null);
                    return;
                }
                fs.readFile(filePath, (error, data) => {
                    if (error) {
                        reject(error);
                    } else {
                        resolve(data);
                    }
                });
            });
        });
    }

    /**
     * 保存文件
     * @param filePath 文件路径
     * @param data 写入数据
     * @param appendFlag 模式(true:追加   false:覆写)
     * @returns 是否保存成功
     */
    public static async SaveFile(filePath: string, data: Buffer, appendFlag: boolean): Promise<boolean> {
        return new Promise((resolve, reject) => {
            if (!filePath) {
                resolve(false);
                return;
            }
            const dir = path.dirname(filePath);
            fs.mkdir(dir, { recursive: true }, (err) => {
                if (err) {
                    reject(err);
                    return;
                }
                const flags = appendFlag ? 'a' : 'w';
                fs.writeFile(filePath, data, { flag: flags }, (error) => {
                    if (error) {
                        reject(error);
                    } else {
                        resolve(true);
                    }
                });
            });
        });
    }
}
