// @ts-check

const os = require('os');
const yaml = require('yaml');
const readSource = require('./readSource.cjs');
const transform = require('./transform.cjs');
const renderSass = require('./renderSass.cjs');
const renderJs = require('./renderJs.cjs');
const { SassValue } = require('./SassValue.cjs');
const sassTag = require('./SassValue.cjs').tag;

const sassComment = `// stylelint-disable
// DO NOT EDIT THIS FILE.  This is a gitignored artifact created by Webpack.
// Design tokens should be edited in _patterns/00-config/config.design-tokens.yml`;

const jsComment = `/* eslint-disable */
// DO NOT EDIT THIS FILE.  This is a gitignored artifact created by Webpack.
// Design tokens should be edited in _patterns/00-config/config.design-tokens.yml`;

/**
 * Webpack loader for config.design-tokens.yml
 *
 * Creates the processed JavaScript and Sass files and then calls the
 * async callback with the transformed YAML.
 * @this {import('webpack').LoaderContext<{}>}
 * @param {string} source
 */
function configLoader(source) {
  const callback = this.async();
  try {
    readSource(source)
      .then(transform)
      .then(
        /**
         * @this {import('webpack').LoaderContext<{}>}
         * @param {import('./types').TransformedSource} transformed
         */
        transformed => {
          const sass = sassComment + os.EOL + renderSass(transformed.data);
          const js = jsComment + os.EOL + renderJs(transformed.data);
          this.emitFile(
            '../source/00-config/_design-tokens.artifact.scss',
            sass
          );
          this.emitFile('../source/00-config/_GESSO.es6.js', js);
          callback(
            null,
            yaml.stringify(
              transformed.data,
              (_key, value) =>
                value instanceof SassValue
                  ? {
                      sass: value.sass,
                      fallback: value.fallback,
                    }
                  : value,
              {
                customTags: [sassTag],
              }
            )
          );
        }
      );
    return source;
  } catch (err) {
    return callback(err);
  }
}

module.exports = configLoader;
