'use strict'

const gulp = require('gulp')
const $ = require('gulp-load-plugins')()

const browserSync = require('browser-sync').create()
const runSequence = require('run-sequence')
const rimraf = require('rimraf')

let distTask = false

gulp.task('default', ['dev'])


gulp.task('dev', cb => {
  distTask = false
  runSequence(
    ['test', 'test:watch', 'styles:watch', 'templates:watch']
  )

  runSequence(
    ['clear'],
    ['scripts', 'styles', 'templates'],
    ['browser-sync']
    , cb)
})

gulp.task('dist', cb => {
  distTask = true

  runSequence(
    ['test', 'browser-sync']
  )

  runSequence(
    ['clear'],
    ['scripts', 'styles'],
    ['templates']
    , cb)
})

gulp.task('clear', (cb) => rimraf('./dist', cb))
gulp.task('scripts', () => scripts('./app/scripts/app.js', './dist/scripts/', true))
gulp.task('server', () => server('./dist'))

gulp.task('templates', () => {
  const manifest = distTask ? require('./dist/rev-manifest.json') : ''

  return gulp.src('./app/index.html')
    .pipe($.if(distTask, $.revManifestReplace({
      base: '.',
      manifest: manifest
    })))
    .pipe($.if(distTask, $.htmlmin({
      removeComments: true,
      collapseWhitespace: true
    })))
    .pipe(gulp.dest('./dist'))
    .pipe(browserSync.stream())
})

gulp.task('templates:watch', () => {
  return gulp.watch('./app/index.html', ['templates'])
})

gulp.task('styles', () => {
  return gulp.src('./app/styles/styles.less')
    .pipe($.sourcemaps.init())
    .pipe($.less())
    .on('error', handleError)
    .pipe($.autoprefixer({browsers: ['last 2 versions', 'Firefox ESR', 'ie >= 9']}))
    .pipe($.if(distTask, $.minifyCss()))
    .pipe($.if(distTask, $.rev()))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('./dist/styles'))
    .pipe($.if(distTask, $.rev.manifest('dist/rev-manifest.json', {base: './dist', merge: true})))
    .pipe($.if(distTask, gulp.dest('./dist')))
    .pipe(browserSync.stream({match: '**/*.css'}))
})

gulp.task('styles:watch', () => {
  return gulp.watch('./app/styles/**', ['styles'])
})

gulp.task('test', () => {
  gulp.src('./test/**/*.js')
    .pipe($.ava())
    .on('error', handleError)
})

gulp.task('test:watch', () => {
  return gulp.watch(['./test/**/*.js', './app/scripts/**/*.js'], ['test'])
})

// functions

const server = (baseDir) => {
  browserSync.init({
    server: {
      baseDir: baseDir
    },
    ghostMode: false,
    port: 8080,
    open: false
  })
}

const scripts = (from, to, watch) => {
  return gulp.src(from)
    .pipe($.webpack({
      watch: watch,
      devtool: 'source-map',
      output: { filename: from.split('/').reverse()[0] },
      module: {
        loaders: [{
          test: /\.js$/,
          exclude: /(node_modules|dist|test)/,
          loader: 'babel',
          query: { presets: ['es2015', 'stage-2'] }
        }]
      }
    }))
    .pipe(gulp.dest(to))
}

function handleError (err) {
  $.util.log($.util.colors.red(`Error: ${ err.message }`))
  // keeps gulp from hanging when error happens
  this.emit('end')
}

@@ -855,17 +855,16 @@
 dist'))%0A
-%0A
 gulp.tas
@@ -888,388 +888,47 @@
  =%3E 
-%7B%0A  const manifest = distTask ? require('./dist/rev-manifest.json') : ''%0A%0A  return gulp.src('./app/index.html')%0A    .pipe($.if(distTask, $.revManifestReplace(%7B%0A      base: '.',%0A      manifest: manifest%0A    %7D)))%0A    .pipe($.if(distTask, $.htmlmin(%7B%0A      removeComments: true,%0A      collapseWhitespace: true%0A    %7D)))%0A    .pipe(gulp.dest('./dist'))%0A    .pipe(browserSync.stream())%0A%7D
+templates('./app/index.html', './dist')
 )%0A%0Ag
@@ -2525,16 +2525,411 @@
 to))%0A%7D%0A%0A
+const templates = (from, to) =%3E %7B%0A  const manifest = distTask ? require(%60$%7B to %7D/rev-manifest.json%60) : ''%0A%0A  return gulp.src(from)%0A    .pipe($.if(distTask, $.revManifestReplace(%7B%0A      base: '.',%0A      manifest: manifest%0A    %7D)))%0A    .pipe($.if(distTask, $.htmlmin(%7B%0A      removeComments: true,%0A      collapseWhitespace: true%0A    %7D)))%0A    .pipe(gulp.dest(to))%0A    .pipe(browserSync.stream())%0A%7D%0A%0A
 function

refactor templates into separate function