// @ts-check
const config = require("../config");
const partialPreFilename = config.filenames.faviconsPartial.replace(
  "blade.php",
  "html"
);
const partialFilename = config.filenames.faviconsPartial;

function getFaviconsOpts() {
  const { getProjectTitle, getOptions } = require("../utils");

  return getOptions("config.favicons", {
    appName: getProjectTitle(), // Your application's name. `string`
    appDescription: "", // config.pkg.description, // Your application's description. `string`
    version: config.pkg.version, // Your application's version string. `string`
    url: process.env.APP_URL,
    appShortName: null, // Your application's short_name. `string`. Optional. If not set, appName will be used
    developerName: null, // Your (or your developer's) name. `string`
    developerURL: null, // Your (or your developer's) URL. `string`
    display: "standalone", // Preferred display mode: "fullscreen", "standalone", "minimal-ui" or "browser". `string`
    background: "#fff", // Background colour for flattened icons. `string`
    theme_color: "#fff", // Theme color user for example in Android's task switcher. `string`
    // appleStatusBarStyle: "black-translucent", // Style for Apple status bar: "black-translucent", "default", "black". `string`
    dir: "auto", // Primary text direction for name, short_name, and description
    lang: "it", // Primary language for name and short_name
    orientation: "any", // Default orientation: "any", "natural", "portrait" or "landscape". `string`
    scope: "/", // set of URLs that the browser considers within your app
    start_url: "/?homescreen=1", // Start URL when launching the application from a device. `string`
    pixel_art: false, // Keeps pixels "sharp" when scaling up, for pixel art.  Only supported in offline mode.
    loadManifestWithCredentials: false, // Browsers don't send cookies when fetching a manifest, enable this to fix that. `boolean`
  });
}

/**
 * Generate favicons from a single `favicon.png` image and put theme in the
 * assets folder. Put the generated html references inside the theme partials
 * so that it can be included in the main layout.
 */
function faviconsGenerate() {
  const gulp = require("gulp");
  const gulpIf = require("gulp-if");
  const faviconsStream = require("favicons").stream;
  const fancyLog = require("fancy-log");
  const paths = require("../paths");
  const { getPublicUrls } = require("../utils");
  const options = getFaviconsOpts();

  return gulp
    .src(paths.join(paths.frontend.src.favicons, "favicon.png"))
    .pipe(
      faviconsStream({
        ...options,
        // non overridable options
        path: getPublicUrls().favicons,
        html: partialPreFilename,
        pipeHTML: true,
        replace: true,
      })
    )
    .on("error", fancyLog)
    .pipe(
      gulpIf(
        // @ts-ignore
        `!${partialPreFilename}`,
        gulp.dest(paths.frontend.dest.favicons)
      )
    )
    .pipe(
      // @ts-ignore
      gulpIf(partialPreFilename, gulp.dest(paths.frontend.dest.automated))
    );
}

/**
 * Rename the partial to `blade.php` templates extensions, we cannot do this
 * in the `favicons` generate task because it doesn't work if we change the
 * `html` option value to a filename with an extension different than `.html`.
 */
function faviconsPartial() {
  const gulp = require("gulp");
  const header = require("gulp-header");
  const rename = require("gulp-rename");
  const paths = require("../paths");
  const { getHeaderAutogeneration } = require("../utils");

  return gulp
    .src(paths.join(paths.frontend.dest.automated, partialPreFilename))
    .pipe(rename(partialFilename))
    .pipe(header(`{{-- ${getHeaderAutogeneration()} --}}\n\n`))
    .pipe(gulp.dest(paths.frontend.dest.automated));
}

/**
 * It seems that chrome does a request to `/favicon.ico` despite all favicons
 * being defined with different hrefs, so we just copy it over in the public
 * directory once all the favicons are generated (29/09/2020)
 */
function faviconsCopyRoot() {
  const gulp = require("gulp");
  const paths = require("../paths");

  return gulp
    .src(paths.join(paths.frontend.dest.favicons, "favicon.ico"))
    .pipe(gulp.dest(paths.frontend.dest.public));
}

/**
 * Clean up the autogenerated `.html` favicons file (renamed in `blade.php` from the
 * above task).
 */
function faviconsClean() {
  const paths = require("../paths");
  const del = require("del");

  return del(paths.join(paths.frontend.dest.automated, partialPreFilename));
}

/**
 * Favicons dev quick copy
 */
function faviconsDevCopy() {
  const gulp = require("gulp");
  const paths = require("../paths");

  return gulp
    .src(paths.join(paths.frontend.src.favicons, "favicon.png"))
    .pipe(gulp.dest(paths.join(paths.frontend.dest.favicons)));
}

function faviconsDevPartial() {
  const gulp = require("gulp");
  const footer = require("gulp-footer");
  const rename = require("gulp-rename");
  const paths = require("../paths");
  const { getPublicUrls } = require("../utils");
  let dummyFaviconUrl = getPublicUrls().favicons + "favicon.png";

  return (
    gulp
      .src(paths.join(paths.self.templates, "dummy.blade.php"))
      // @ts-ignore
      .pipe(footer(`<link rel="shortcut icon" href="${dummyFaviconUrl}">`))
      // @ts-ignore
      .pipe(rename(partialFilename))
      .pipe(gulp.dest(paths.frontend.dest.automated))
  );
}

/**
 * Favicons dev dummy templates and icon
 */
function faviconsDev(callback) {
  const gulp = require("gulp");
  return gulp.series(faviconsDevCopy, faviconsDevPartial)(callback);
}

/**
 * Collect subtasks in a single task that respect the gulp async lifecycle by
 * calling the callback on completion.
 */
function favicons(callback) {
  const gulp = require("gulp");

  return config.isProduction
    ? gulp.series(
        faviconsGenerate,
        faviconsPartial,
        faviconsClean,
        faviconsCopyRoot
      )(callback)
    : gulp.series(faviconsDev)(callback);
}

module.exports = {
  faviconsClean,
  faviconsDev,
  favicons,
};
