import { dest, parallel, series, src, task, watch } from 'gulp'
import mainNPMFiles from 'npmfiles'
const $ = require('gulp-load-plugins')()

// ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  --- 
// Configuration objects.
// ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  --- 

const cfg = {
  scss: {
    src: './static/scss/src',
    lib: './static/scss/lib',
    dst: './static/css',
    bundle: 'styles'
  },
  js: {
    src: './static/js/src',
    lib: './static/js/lib',
    dst: './static/js',
    bundle: 'scripts'
  }
}

/** List of sass stylesheets. */
const sassFilesOrdered = [
  `${cfg.scss.src}/_reset.scss`,
  `${cfg.scss.src}/_bootstrap-grid.scss`,
  `${cfg.scss.src}/_settings.scss`,
  `${cfg.scss.src}/_fancybox.scss`,
  `${cfg.scss.src}/_general.scss`,
  `${cfg.scss.src}/_typography.scss`,
  `${cfg.scss.src}/**/*.scss`,
  `${cfg.scss.lib}/**/*.scss`,
]

/** List of entrypoints to our & dependency libs */
const jsFilesOrdered = [
  `!${cfg.js.lib}/svg4everybody.legacy.js`,
  `${cfg.js.lib}/jquery.js`,
  `${cfg.js.lib}/jquery.validate.js`,
  `${cfg.js.lib}/**/*.js`,
  `${cfg.js.src}/**/*.js`
]

// ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  --- 

const jsFilter = $.filter('**/*.js', { restore: true });
const cssFilter = $.filter('**/*.css');

task('libcopy', () => src(mainNPMFiles({ showWarnings: true }))
  .pipe(jsFilter)
  .pipe(dest(cfg.js.lib))
  .pipe(jsFilter.restore)
  .pipe(cssFilter)
  .pipe($.rename({ extname: '.scss' }))
  .pipe(dest(cfg.scss.lib))
)

const sassDev = async () => src(sassFilesOrdered)
  .pipe($.sourcemaps.init())
  .pipe($.concat(`${cfg.scss.bundle}.css`))
  .pipe($.sass({outputStyle: 'expanded'}))
  .pipe($.autoprefixer({ cascade: false }))
  .pipe($.sourcemaps.write('.'))
  .pipe(dest(cfg.scss.dst))
  .pipe($.livereload())

const sassProd = async () => src(sassFilesOrdered)
  .pipe($.sourcemaps.init())
  .pipe($.concat(`${cfg.scss.bundle}.min.css`))
  .pipe($.sass({ outputStyle: 'compressed' }))
  .pipe($.autoprefixer({ cascade: false }))
  .pipe($.sourcemaps.write('.'))
  .pipe(dest(cfg.scss.dst))

task('sass:dev:watch', sassDev)
task('sass:dev', sassDev)
task('sass:prod', sassProd)

const jsDev = async () => src(jsFilesOrdered)
  .pipe($.concat(`${cfg.js.bundle}.js`))
  .pipe(dest(cfg.js.dst))
  
const jsProd = async () => src(jsFilesOrdered)
  .pipe($.sourcemaps.init())
  .pipe($.concat(`${cfg.js.bundle}.min.js`))
  .pipe($.uglify())
  .pipe($.sourcemaps.write('.'))
  .pipe(dest(cfg.js.dst))

task('js:dev:watch', jsDev)
task('js:dev', jsDev)
task('js:prod', jsProd)

// ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---
// Top-level tasks
// ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---  ---

task('html:dev:watch', async () => 
  src(['./*.html']).pipe($.livereload())
)

task('watch', () => {
  $.livereload.listen()
  watch(['*.html'], series('html:dev:watch'))
  watch([`${cfg.scss.src}/*.scss`], series('sass:dev:watch'))
  watch([`${cfg.js.src}/*.js`], series('js:dev:watch'))
})

task('dev', series('libcopy', parallel('sass:dev', 'js:dev'), 'watch'));
task('prod', series('libcopy', parallel('sass:dev', 'js:dev', 'sass:prod', 'js:prod')));
task('default', series('dev'));
