#! /usr/bin/env node

const commandLineArgs = require('command-line-args');
const fs = require('fs');
const path = require('path');
const s3 = require('s3');

const optionDefinitions = [
  { name: 'bucket', alias: 'b', type: String },
  { name: 'dev', alias: 'd', type: Boolean },
  { name: 'player', type: Boolean},
  { name: 'prefix', alias: 'p', type: String },
  { name: 'root', alias: 'r', type: String },
  { name: 'target', alias: 't', type: String },
  { name: 'version', alias: 'v', type: String },
];

const options = commandLineArgs(optionDefinitions);

const pkg = require(`${options['root']}/package.json`);
const version = options.dev ? pkg.version_dev : pkg.version;


syncDist(options['target'], options['bucket'], options['prefix']);

function createS3Client() {
  let creds;
  const s3Options = Object.assign({}, pkg.config.aws.s3);

  try {
    creds = JSON.parse(
      fs.readFileSync(path.resolve(`${options['root']}/aws.private.json`), 'utf8')
    );
  } catch (e) {
    console.error('Error finding/parsing aws.private.json');
    throw e;
  }

  if (creds.accessKeyId == null || creds.secretAccessKey == null) {
    throw new TypeError(
      'Error could not fine accessKeyId or secretAccessKey in aws.private.json file.'
    );
  }

  Object.assign(s3Options, creds);

  // s3Options is what is used by the AWS SDK
  // See: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html#constructor-property

  return s3.createClient({
    // default options
    maxAsyncS3: 20,
    s3RetryCount: 3,
    s3RetryDelay: 1000,
    multipartUploadThreshold: 20971520,
    multipartUploadSize: 15728640,
    cacheTTL: 0,
    s3Options
  });
}

function promiseWrapUploader(uploader) {
  return new Promise(function (resolve, reject) {
    uploader.on('error', reject);
    uploader.on('end', resolve);
    uploader.on('fileUploadEnd', function (localFilePath, s3Key) {
      console.log(`Pushed ${localFilePath} to ${s3Key}`);
    });

  });
}

function syncDist(target, bucket, prefix) {
  let uploadOptions = {
    localDir: 'dist/' + target,

    deleteRemoved: false, // keep older versions
    s3Params: {
      Bucket: bucket,
      Prefix: prefix,
      // can add options for putObject command
      // see: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property
    }
  };

  let s3Client = createS3Client();

  return promiseWrapUploader(s3Client.uploadDir(uploadOptions))
    .catch(function (error) {
      console.error('There was an error during the release process!');
      console.error(error.stack);
      return null;
    })
    .then(function (result) {
      if (result == null) {
        return;
      }
      console.log('Release finished');
    });
}
