import * as path from "path";
import * as fs from "fs";
import * as Os from "os";
import ProgressBar from "progress";
import OSS from "ali-oss";

export default class AutoUpload {
    options = {
        dir: undefined,
        originDir: undefined
    };

    client = null;
    bar = null;
    private _files: any;
    private existFiles: number = 0;
    private uploadFiles: number = 0;
    private errorFiles: number = 0;

	constructor(props) {

		const defaultOptions = {
			dir: undefined,
			originDir: undefined
		}

		this.options = Object.assign({}, defaultOptions, props);

		if (!this.options.dir || !this.options.originDir) {
			console.error("缺少参数，初始化失败");
		}

		this.init();
	}

	init() {
		this.client = new OSS({
			region: "oss-cn-hangzhou",
			accessKeyId: "LTAI5tPUSSxgkEmKPAfVXUQQ",
			accessKeySecret: "6sk3EDd1BYrXlAUoh8maMuN7hOMkh1",
			bucket: "duiba",
		});

		this.bar = new ProgressBar(`文件上传中 [:bar] :current/${this.files().length} :percent :elapseds`, {
			complete: "●",
			incomplete: "○",
			width: 20,
			total: this.files().length,
			callback: () => {
				console.log("%cAll complete.", "color: green");
                console.log(`%c本次队列文件共${this.files().length}个，已存在文件${this.existFiles}个，上传文件${this.uploadFiles}个，上传失败文件${this.errorFiles}个`, "color: green");
			}
		})
		return this;
	}

	files() {
		if (this._files) return this._files;
		this._files = [];

		/**
		 * 文件遍历方法
		 * @param filePath 需要遍历的文件路径
		 */
		const fileDisplay = (filePath) => {
			//根据文件路径读取文件，返回文件列表
			const files = fs.readdirSync(filePath);

			files.forEach((filename) => {
				//获取当前文件的绝对路径
				const fileDir = path.join(filePath, filename);
				//根据文件路径获取文件信息，返回一个fs.Stats对象
				const stats = fs.statSync(fileDir);
				const isFile = stats.isFile();//是文件
				const isDir = stats.isDirectory();//是文件夹
				if (isFile) {
					this._files.push(fileDir);
				} else if (isDir) {
					fileDisplay(fileDir);//递归，如果是文件夹，就继续遍历该文件夹下面的文件
				}
			});
		}

		//调用文件遍历方法
		fileDisplay(this.options.dir);
		return this._files;
	}

	async start() {
		const platform = Os.platform();

		const ps = this.files().map((file) => {

			let relativePath = "";

			if (platform === "win32") {
				console.log("win平台")
				relativePath = file.replace(this.options.dir + "\\", "");
				relativePath = relativePath.replace(/\\/g, "/");
			} else {
				relativePath = file.replace(this.options.dir + "/", "");
			}

			this.existFiles = 0;
			this.uploadFiles = 0;
			this.errorFiles = 0;

			const originPath = `${this.options.originDir}${relativePath}`;

			return (async () => {
				let originFile = null;

				originFile = await this.client.head(originPath)
					.catch((error) => originFile = error);

				try {
					if (originFile.status === 404) {
						await this.client.put(originPath, file);
						this.uploadFiles += 1;
					} else {
						this.existFiles += 1;
					}
				} catch (error) {
					this.errorFiles += 1;
				}
				this.bar.tick();
			})();
		});

		await Promise.all(ps).catch((err) => {
			console.error("上传错误", err);
		});

	}
}
