// update-deps.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache 2.0

'use strict';

const path = require('path');
require('dotenv').config();

const { spawn } = require('child_process');

const { SiteLog } = require(path.join(__dirname, 'lib', 'site-lib'));

module.rootPath = __dirname;
module.pkg = require(path.join(module.rootPath, 'package.json'));
module.pinnedPackages = require(path.join(module.rootPath, 'config', 'pinned-packages'));

module.config = {
  component: { name: 'Webapp Dependency Updater', slug: 'webapp-update-deps' },
};

module.log = new SiteLog(module, module.config.component);

module.runCommand = async (command, args) => {
  return new Promise((resolve, reject) => {
    module.log.info(command, { args });
    const cmd = spawn(command, args);
    cmd.stdout.on('data', (data) => {
      const output = data.toString('utf8');
      module.log.info(output);
    });
    cmd.stderr.on('data', (data) => {
      const output = data.toString('utf8');
      module.log.error(output);
    });
    cmd.on('error', (err) => {
      reject(err);
    });
    cmd.on('close', (code) => {
      resolve(code);
    });
  });
};

module.generateDepKeys = (dependencies) => {
  const depKeys = Object.keys(dependencies).map((packageName) => {
    const pin = module.pinnedPackages[packageName];
    if (!pin) {
      return packageName;
    }
    if (pin.exact) {
      return `${packageName}@${pin.version} --exact`;
    }
    return `${packageName}@${pin.version}`;
  });
  return depKeys;
};

(async ( ) => {

  try {
    module.log.info('updating dependencies');
    const depKeys = module.generateDepKeys(module.pkg.dependencies);
    await module.runCommand('yarn', ['add', ...depKeys]);
  } catch (error) {
    module.error('failed to update dependencies', { error });
    process.exit(-1);
  }

  try {
    module.log.info('updating dev dependencies');
    const depKeys = module.generateDepKeys(module.pkg.devDependencies);
    await module.runCommand('yarn', ['add', '--dev', ...depKeys]);
  } catch (error) {
    module.error('failed to update dev dependencies', { error });
    process.exit(-1);
  }

  module.log.info('dependencies updated successfully. Good luck with that!');
})();