import qiniu from 'qiniu';
import Promise from 'promise';
import { join } from 'path';

class QiniuPlugin {

  constructor(options) {
    this.options = Object.assign({}, options);
    qiniu.conf.ACCESS_KEY = this.options.ACCESS_KEY;
    qiniu.conf.SECRET_KEY = this.options.SECRET_KEY;
  }

  apply(compiler) {
    compiler.plugin('after-emit', (compilation, callback) => {
      const assets = compilation.assets;
      const hash = compilation.hash;
      const {
        bucket,
        include,
      } = this.options;
      let {
        path = '[hash]',
      } = this.options;

      path = path.replace('[hash]', hash);

      const promises = Object.keys(assets).filter((fileName) => {
        let valid = assets[fileName].emitted;
        if (include) {
          valid = valid
            && include.some(
              (includeFileName) => {
                if (includeFileName instanceof RegExp) {
                  return includeFileName.test(fileName);
                }
                return includeFileName === fileName;
              },
            );
        }
        return valid;
      }).map((fileName) => {
        const key = join(path, fileName);
        const putPolicy = new qiniu.rs.PutPolicy(`${bucket}:${key}`);
        const token = putPolicy.token();
        const extra = new qiniu.io.PutExtra();

        const promise = new Promise((resolve, reject) => {
          const begin = Date.now();
          qiniu.io.putFile(token, key, assets[fileName].existsAt, extra, (err, ret) => {
            if (!err) {
              resolve({
                ...ret,
                duration: Date.now() - begin,
              });
            } else {
              reject(err);
            }
          });
        });

        return promise;
      });

      Promise
        .all(promises)
        .then((res) => {
          console.log(res); // eslint-disable-line no-console
          callback();
        })
        .catch((e) => {
          callback(e);
        });
    });
  }
}

export default QiniuPlugin;

@@ -123,24 +123,165 @@
 (options) %7B%0A
+    if (!options %7C%7C !options.ACCESS_KEY %7C%7C !options.SECRET_KEY) %7B%0A      throw new Error('ACCESS_KEY and SECRET_KEY must be provided');%0A    %7D%0A
     this.opt

throw error if options is not provided