/* ======================================================== */
/* global require */
const { task, src, dest, watch, series, parallel } = require("gulp"); // Собственно gulp

const clean = require("gulp-clean"); // удаление файлов и каталогов

const include = require("gulp-file-include");
const version = require("gulp-version-number"); // версионность файлов

const postcss = require("gulp-postcss"); // Пост-обработка CSS
const postcssPresetEnv = require("postcss-preset-env"); // CSS Next
const atImport = require("postcss-import"); // парсинг и включение импорта CSS

const sourcemaps = require("gulp-sourcemaps"); // карты исходного кода

const webpack = require("webpack-stream");
const compiler = require("webpack");

const imagemin = require("gulp-image"); // оптимизация картинок
const cache = require("gulp-cache");

const browsersync = require("browser-sync").create(); // обновление налету

/* ========================================================== */

/**
 * Настройки CSS
 */
const postcssOptions = [
	atImport(),
	postcssPresetEnv({
		stage: 0,
		autoprefixer: {
			grid: true,
			browsers: ["last 4 versions", "ie >= 11", "iOS >= 9"]
		}
	})
];

/**
 * gulp-file-include Options
 */
const devIncludeOptions = {
	prefix: "@@",
	basepath: "@file",
	context: {
		env: "DEV",
		path: "/assets",
		version: Date.now()
	}
};

const prodIncludeOptions = {
	prefix: "@@",
	basepath: "@file",
	context: {
		env: "MS",
		path: "/templates/nikolin-day-annonce-2019/assets",
		version: Date.now()
	}
};

/**
 * gulp-version Options
 */
const versionOptions = {
	value: "%MDS%",
	append: {
		key: "v",
		to: ["css", "js", ["image", "%TS%"]]
	}
};

/* ================================================================= */

/**
 * CLEAN
 * Полная очистка
 */
const Clean = cb => {
	cb();
	return src(["./dev", "./prod"], { read: false, allowEmpty: true }).pipe(clean());
};
task("CLEAN", Clean);

// ========================== CSS ============================
const devCss = cb => {
	cb();
	return src("./src/assets/css/*.css")
		.pipe(sourcemaps.init())
		.pipe(postcss(postcssOptions))
		.pipe(include(devIncludeOptions))
		.pipe(sourcemaps.write("."))
		.pipe(dest("./dev/assets/css"))
		.pipe(browsersync.stream());
};

// Собираем CSS
const prodCss = cb => {
	cb();
	return src("./src/assets/css/*.css")
		.pipe(postcss(postcssOptions))
		.pipe(include(prodIncludeOptions))
		.pipe(dest("./prod/assets/css"));
};

// ================== JS ============================
// Компилируем и собираем все js файлы проекта
const devJs = cb => {
	cb();
	return src("./src/assets/js/*.js")
		.pipe(
			webpack(require("./webpack.dev.js"), compiler, function(err, stats) {
				// console.log( err, stats );
			})
		)
		.pipe(dest("./dev/assets/js"))
		.pipe(browsersync.stream());
};

// Обрабатываем js файлы библиотек и проекта
const prodJs = cb => {
	cb();
	return src("./src/assets/js/*.js")
		.pipe(
			webpack(require("./webpack.prod.js"), compiler, function(err, stats) {
				// console.log( err, stats );
			})
		)
		.pipe(dest("./prod/assets/js"));
};

// ================== IMG ============================
// Оптимизация картинок для dev
const devImgComponents = cb => {
	cb();
	// prettier-ignore
	return src([
		"node_modules/lightgallery.js/dist/img/*",
		"./src/assets/img/**/*",
		"./src/components/**/*.png",
		"./src/components/**/*.jpg",
		"./src/components/**/*.jpeg",
		"./src/components/**/*.gif",
		"./src/components/**/*.svg"
	])
		.pipe(cache(imagemin()))
		.pipe(dest("./dev/assets/img"));
};

// Оптимизация картинок для prod
const prodImgComponents = cb => {
	cb();
	// prettier-ignore
	return src([
		"node_modules/lightgallery.js/dist/img/*",
		"src/assets/img/**/*",
		"src/components/**/*.png",
		"src/components/**/*.jpg",
		"src/components/**/*.jpeg",
		"src/components/**/*.gif",
		"src/components/**/*.svg"
	])
		.pipe(cache(imagemin()))
		.pipe(dest("prod/assets/img"));
};

// ================== FONTS ============================
const devFonts = cb => {
	cb();
	// prettier-ignore
	return src([
		"node_modules/lightgallery.js/dist/fonts/*",
		"src/assets/fonts/**/*"
	])
		.pipe(dest("dev/assets/fonts"));
};

const prodFonts = cb => {
	cb();
	// prettier-ignore
	return src([
		"node_modules/lightgallery.js/dist/fonts/*",
		"src/assets/fonts/**/*"
	])
		.pipe(dest("prod/assets/fonts"));
};

// ================== HTML ============================
// HTML для dev
const devHtml = () => {
	return src(["src/**/*.html", "!src/assets/*.html", "!src/components/**/*.html"])
		.pipe(include(devIncludeOptions))
		.pipe(version(versionOptions))
		.pipe(dest("./dev"));
};

// HTML для prod
const prodHtml = cb => {
	cb();
	return src(["src/**/*.html", "!src/assets/*.html", "!src/components/**/*.html"])
		.pipe(include(prodIncludeOptions))
		.pipe(version(versionOptions))
		.pipe(dest("./prod"));
};

// ================== DEV ============================
// Слежение за dev
function browserSync() {
	browsersync.init({
		server: {
			baseDir: "./dev/"
		},
		port: 3000
	});
}

function browserSyncReload(done) {
	browsersync.reload();
	done();
}

task(
	"DEV",
	series(devImgComponents, devFonts, devCss, devJs, devHtml, () => {
		watch(["./src/assets/css/*.css", "./src/components/**/*.css"], devCss);
		watch(["./src/assets/js/*.js", "./src/components/**/*.js"], devJs);
		watch("./src/**/*.html", series(devHtml, browserSyncReload));
		watch(["./src/assets/img/**/*", "./src/components/**/*.gif", "./src/components/**/*.jpg", "./src/components/**/*.jpeg", "./src/components/**/*.png", "./src/components/**/*.svg"], parallel(devImgComponents));

		browserSync();
	})
);

// ================== PROD ============================
// Публикация на prod
task("PROD", series(prodImgComponents, prodFonts, prodCss, prodJs, prodHtml));
