const devcert = require('devcert');
const fs = require('fs-extra');

/**
@typedef {{
  domain: string;
  keyDestination: string;
  certDestination: string;
  caDestination?: string;
  mode: 'build' | 'watch';
}} ValidatedConfig
@typedef {Partial<Omit<ValidatedConfig, 'mode'>> & { mode: string; }} Config
 */

/**
 * @param {Config} config
 * @returns {Promise<ValidatedConfig>}
 */
async function validate({ domain, keyDestination, certDestination, caDestination, mode = 'build' }) {
  if (!domain) {
    throw new Error('domain is required');
  }

  if (!keyDestination) {
    throw new Error('keyDestination is required');
  }

  if (!certDestination) {
    throw new Error('certDestination is required');
  }

  if (mode !== 'build') {
    throw new Error('Only "build" mode is supported');
  }

  return {
    domain,
    keyDestination,
    certDestination,
    caDestination,
    mode,
  };
}

/**
 * @param {Config} config
 */
module.exports = async function devcertTask(config) {
  const validatedConfig = await validate(config);
  // https://github.com/davewasmer/devcert#options
  const { key, cert, ca } = await devcert.certificateFor(validatedConfig.domain, {
    getCaBuffer: true,
    skipHostsFile: true,
  });

  await Promise.all([
    fs.outputFile(validatedConfig.keyDestination, key),
    fs.outputFile(validatedConfig.certDestination, cert),
    validatedConfig.caDestination ? fs.outputFile(validatedConfig.caDestination, ca) : Promise.resolve(),
  ]);
};
