const { src, dest, watch, parallel } = require('gulp');
const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
const minimist = require('minimist');
const tsConfig = require('./tsconfig.json');
const webpack = require('webpack-stream');
const webpackConfig = require('./webpack.config');
const templating = require('./templates');

const argv = minimist(process.argv);

function buildFrontend() {
  let config = webpackConfig;
  if (argv.dev) {
    config = { ...config, ...{ mode: 'development' } };
  }
  if (argv.watch) {
    config = { ...config, ...{ watch: true } };
  }

  return src(config.entry)
    .pipe(webpack(config))
    .pipe(dest(config.output.path));
}

function buildIndexHtml(cb) {
  let isDev = false;
  if (argv.dev) {
    isDev = true;
  }
  const html = templating.compile(isDev);

  fs.writeFileSync(path.resolve(webpackConfig.output.path, 'index.html'), html);

  cb();
}

function transpileTypescript(cb) {
  const command = path.resolve(process.cwd(), 'node_modules', '.bin', 'tsc');
  exec(command, (err, stdout, stderr) => {
    if (stdout) {
      console.log(stdout);
    }
    if (stderr) {
      console.log(stderr);
    }
    cb(err);
  });
}

function build(cb) {
  if (argv.watch) {
    watch(tsConfig.include, { ignoreInitial: false }, transpileTypescript);
    watch('./templates/**/*', { ignoreInitial: false }, buildIndexHtml);
    buildFrontend();
  } else {
    parallel(transpileTypescript, buildIndexHtml, buildFrontend)(cb);
  }
}
build.flags = {
  '--dev': 'builds in development mode',
  '--watch': 'watches the files',
};

exports.build = build;
