/* eslint-disable no-console */
const { exec } = require('child_process')
function childProcess (process, print) {
  return new Promise((resolve, reject) => {
    print.info('[INFO] Installing dependencies...')
    print.info(`> ${process}`)
    const cp = exec(process)

    cp.stdout.on('data', (data) => {
      console.log(data.toString())
    })

    cp.on('exit', () => {
      resolve()
    })

    cp.on('error', (error) => {
      reject(error)
    })
  })
}

async function installPkgs (useYarn, pkgs, print) {
  useYarn
    ? await childProcess(`yarn add ${pkgs.join([' '])}`, print)
    : await childProcess(`npm install ${pkgs.join([' '])}`, print)
}

const optionalPackages = {
  mongo: ['mongodb'],
  postgres: ['@herbsjs/herbs2knex', 'pg'],
  sqlserver: ['@herbsjs/herbs2knex', 'tedious'],
  rest: ['express@4.17.1', 'cors@2.8.5', '@herbsjs/herbs2rest'],
  graphql: ['graphql@15.5.1', 'apollo-server@2.25.2',
    'apollo-server-express@2.25.2', 'graphql-tools@8.1.0']
}

const defaultOptions = (options) => {
  return {
    name: options.name ? options.name : 'herbs-project',
    description: options.description ? options.description : 'project generated by herbs CLI S2',
    author: options.author ? options.author : 'herbs CLI',
    license: options.license ? options.license : 'MIT',
    mongo: options.mongo ? options.mongo : false,
    postgres: options.postgres ? options.postgres : false,
    sqlserver: options.sqlserver ? options.sqlserver : false,
    yarn: options.yarn ? options.yarn : false,
    graphql: options.graphql ? options.graphql : false,
    rest: options.rest ? options.rest : false
  }
}

module.exports =
  async ({
    template: { generate },
    parameters: {
      options
    },
    print
  }) => async () => {
    options = defaultOptions(options)
    const migration = (options.postgres || options.sqlserver)
      ? `,
      "knex:make": "npx knex --knexfile knexFile.js migrate:make",
      "knex:migrate": "npx knex --knexfile knexFile.js migrate:latest",
      "knex:rollback": "npx knex --knexfile knexFile.js migrate:rollback",
      "knex:makeSeeds": "npx knex --knexfile knexFile.js seed:make",
      "knex:runSeeds": "npx knex --knexfile knexFile.js seed:run"`
      : ''

    await generate({
      template: 'package.json.ejs',
      target: 'package.json',
      props: {
        ...options,
        migration
      }
    })

    await installPkgs(options.yarn, ['@herbsjs/herbs', 'deepmerge'], print)

    let packages = [
      '@herbsjs/herbs2gql',
      '@herbsjs/herbsshelf',
      'sugar-env@1.5.14',
      'dotenv@10.0.0',
      'nodemon',
      'mocha',
      'lodash.camelcase'
    ]

    for (const key of Object.keys(options)) {
      if (key && options[key]) {
        packages = packages.concat(optionalPackages[key])
      }
    }

    await installPkgs(options.yarn, packages, print)
  }
