/* eslint-disable no-param-reassign */
/* eslint-disable no-console */

require('isomorphic-fetch');
const https = require('https');
const fs = require('fs-extra');
const path = require('path');
const decompress = require('decompress');
const buckets = require('../../../constants/buckets');
const assetSources = require('../../../constants/assetSources');

function downloadFile(url, dest) {
  return new Promise((resolve, reject) => {
    const file = fs.createWriteStream(dest);
    https
      .get(url, response => {
        if (response.statusCode >= 300) {
          reject(
            new Error(`HTTP error fetching archive: ${response.statusCode}`),
          );
        } else {
          response.pipe(file);
          file.on('finish', () => {
            file.close(resolve);
          });
        }
      })
      .on('error', err => {
        fs.unlink(dest);
        reject(new Error(err.message));
      });
  });
}

async function downloadFromLiveBucket(files, buildOptions) {
  const bucket = buckets[buildOptions.buildtype];
  const fileManifestPath = 'generated/file-manifest.json';

  console.log(`Downloading assets from ${bucket}...`);

  const fileManifestRequest = await fetch(`${bucket}/${fileManifestPath}`);
  const fileManifest = await fileManifestRequest.json();

  files[fileManifestPath] = {
    path: fileManifestPath,
    contents: new Buffer(JSON.stringify(fileManifest)),
  };

  const entryNames = Object.keys(fileManifest);

  const downloads = entryNames.map(async entryName => {
    let bundleFileName = fileManifest[entryName];
    const bundleUrl = `${bucket}${bundleFileName}`;
    const bundleResponse = await fetch(bundleUrl);

    if (!bundleResponse.ok) {
      throw new Error(`Failed to download asset: ${bundleUrl}`);
    }

    if (bundleFileName.startsWith('/'))
      bundleFileName = bundleFileName.slice(1);

    files[bundleFileName] = {
      path: bundleFileName,
      contents: await bundleResponse.buffer(),
    };

    console.log(`Successfully downloaded asset: ${bundleUrl}`);
  });

  return Promise.all(downloads);
}

async function downloadFromArchive(files, assetSource, buildtype) {
  const archiveUrl = `https://s3-us-gov-west-1.amazonaws.com/vetsgov-website-builds-s3-upload/${assetSource}/${buildtype}.tar.bz2`;

  const localPath = path.join(
    __dirname,
    `../../../../../temp/${buildtype}/site.tar.bz2`,
  );

  const assetsPath = path.dirname(localPath);

  fs.emptyDirSync(assetsPath);

  await downloadFile(archiveUrl, localPath);
  await decompress(localPath, assetsPath);

  fs.readdirSync(path.join(assetsPath, 'generated')).forEach(file => {
    files[`generated/${file}`] = {
      path: `generated/${file}`,
      contents: fs.readFileSync(path.join(assetsPath, 'generated', file)),
    };
  });

  fs.emptyDirSync(assetsPath);
}

function downloadAssets(buildOptions) {
  return async (files, smith, done) => {
    const assetSource = buildOptions['asset-source'];

    if (assetSource === assetSources.DEPLOYED) {
      await downloadFromLiveBucket(files, buildOptions);
    } else {
      await downloadFromArchive(files, assetSource, buildOptions.buildtype);
    }

    done();
  };
}

module.exports = downloadAssets;

@@ -351,16 +351,132 @@
 ces');%0A%0A
+// exits with non-zero if a download failed (for jenkins)%0Aprocess.on('unhandledRejection', up =%3E %7B%0A  throw up;%0A%7D);%0A%0A
 function

exit jenkins with non-zero if cms download fails (#10286)