"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

require("core-js/modules/es.promise");

var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");

_Object$defineProperty(exports, "__esModule", {
  value: true
});

exports.default = void 0;

var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/json/stringify"));

var _keys = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/keys"));

var _forEach = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/for-each"));

var _indexOf = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/index-of"));

var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));

var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/asyncToGenerator"));

var _path = _interopRequireDefault(require("path"));

var _fsExtra = _interopRequireDefault(require("fs-extra"));

var _plugin = _interopRequireDefault(require("@start/plugin"));

/*
 * This script checks if a Component is missing a '_stories' folder, and creates a default one if it's missing.
 * It also checks if there is a 'fixtures' folder in a Component folder, and creates stories from those fixtures, then removes the 'fixtures' folder.
 */
var _default = prefix => (0, _plugin.default)('CREATE STORYBOOK STORIES', ({
  reporter
}) =>
/*#__PURE__*/
(0, _asyncToGenerator2.default)(function* () {
  try {
    return new _promise.default((resolve, reject) => {
      const componentPaths = ['components', 'src/components'];
      const stylesPath = ['styles', 'src/styles'];
      (0, _map.default)(componentPaths).call(componentPaths, path => {
        _fsExtra.default.exists(path, exists => {
          if (exists) {
            start(path, prefix);
          }
        });
      });
      (0, _map.default)(stylesPath).call(stylesPath, path => {
        _fsExtra.default.exists(path, exists => {
          if (exists) {
            createStorybookLessFile(path);
          }
        });
      });
      resolve();
    });
  } catch (e) {
    return _promise.default.reject(e);
  }
}));
/** STORY CREATION **/


exports.default = _default;

const createStoryForComponentFromFixtures = function (prefix, componentName, filePath, folderName, cb) {
  _fsExtra.default.readdir(filePath, (err, files) => {
    if (err) {
      cb(err);
    } else {
      let chapters = [],
          safeToImport = true;

      for (const i in files) {
        const fileName = files[i];

        var currentFile = _path.default.join(filePath, fileName);

        const stats = _fsExtra.default.statSync(currentFile);

        if (stats.isDirectory() || (0, _indexOf.default)(fileName).call(fileName, '.js') < 0) {
          safeToImport = false;
        }
      }

      if (safeToImport) {
        var _context;

        const DynRequire = require('dyn-require');

        const modules = new DynRequire(__dirname + '/../../' + filePath);
        const fixtures = modules.modules;
        (0, _forEach.default)(_context = (0, _keys.default)(fixtures)).call(_context, key => {
          if (fixtures[key] && fixtures[key].default) {
            chapters.push({
              name: key,
              props: fixtures[key].default
            });
          }
        });

        const componentFolder = _path.default.join(__dirname, '/../', 'components', componentName);

        createStoriesFolder(componentName, componentFolder, err => {
          if (err) {
            console.error('- Error: Unable to create _stories folder', err);
          } else {
            createStoryFile(prefix, componentName, componentFolder, err => {
              if (err) {
                if (err !== 'File exists') {
                  return console.error('- Error: Unable to create story file', err);
                }
              }
            });
            createStoryDataFile(componentName, componentFolder, chapters, err => {
              if (err) {
                if (err !== 'File exists') {
                  return console.error('- Error: Unable to create story data file', err);
                }
              }

              if (folderName === 'fixtures') {
                _fsExtra.default.remove(currentFile, err => {
                  if (err) {
                    console.error(err);
                  } else {
                    console.info(' - Info: Removed fixture folder for', componentName);
                  }
                });
              }
            });
          }
        });
      }

      cb();
    }
  });
};

var createStoriesFolder = function (componentName, componentFolder, cb) {
  const storiesPath = _path.default.join(componentFolder, '_stories');

  ensureExists(storiesPath, 484, err => {
    if (err) {
      // handle folder creation error
      cb(err);
    } else {
      // we're all good
      if (err === null) {
        //err is an empty string when the folder already exists
        console.info('- Info: Created _stories folder for', componentName);
      }

      cb(null);
    }
  });
};

var createStoryFile = function (prefix, componentName, componentFolder, cb) {
  const template = `import ${componentName} from '../${componentName}';\nimport storyData from './storyData.js';\nimport '../../../styles/storybook.less';\n\nexport default ({ createStories }) => {\n\tcreateStories(storyData, ${componentName}, '${prefix}.${componentName}', true, true);\n}`;

  const folderPath = _path.default.join(componentFolder, '_stories');

  const storyFilePath = _path.default.join(folderPath, componentName + '.story.js');

  _fsExtra.default.exists(storyFilePath, exists => {
    if (!exists) {
      _fsExtra.default.writeFile(storyFilePath, template, err => {
        if (err) {
          cb(err);
        } else {
          console.info('- Info: Create story file for', componentName);
          cb(null);
        }
      });
    } else {
      cb('File exists');
    }
  });
};

var createStorybookLessFile = function (folderPath) {
  const template = '@import "~@meniga/ui/src/styles/storybook";';

  const lessFilePath = _path.default.join(folderPath, 'storybook.less');

  _fsExtra.default.exists(lessFilePath, exists => {
    if (!exists) {
      _fsExtra.default.writeFile(lessFilePath, template, err => {
        if (err) {
          console.error(err);
        } else {
          console.info('- Info: Created storybook.less file in the styles folder');
        }
      });
    }
  });
};

var createStoryDataFile = function (componentName, componentFolder, chapters, cb) {
  const folderPath = _path.default.join(componentFolder, '_stories');

  const storyDataFilePath = _path.default.join(folderPath, 'storyData.js');

  _fsExtra.default.exists(storyDataFilePath, exists => {
    if (!exists) {
      const chapterJson = [];
      (0, _forEach.default)(chapters).call(chapters, chapter => {
        chapterJson.push(chapter);
      });
      const json = {
        stories: [{
          chapters: chapterJson
        }]
      };
      const template = 'export default ' + (0, _stringify.default)(json, null, 4) + ';';

      _fsExtra.default.writeFile(storyDataFilePath, template, err => {
        if (err) {
          cb(err);
        } else {
          console.info('- Info: Created storyData file for', componentName);
          cb(null);
        }
      });
    } else {
      cb('File exists');
    }
  });
};
/** HELPERS **/


var ensureExists = function (path, mask, cb) {
  if (typeof mask === 'function') {
    // allow the `mask` parameter to be optional
    cb = mask;
    mask = 484;
  }

  _fsExtra.default.mkdir(path, mask, err => {
    if (err) {
      if (err.code == 'EEXIST') cb();else cb(err); // something else went wrong
    } else cb(null); // successfully created folder

  });
};

var searchForFixtures = function (prefix, currentPath) {
  const files = _fsExtra.default.readdirSync(currentPath);

  for (const i in files) {
    const fileName = files[i];

    const currentFile = _path.default.join(currentPath, fileName);

    const stats = _fsExtra.default.statSync(currentFile);

    if (stats.isDirectory()) {
      if (fileName === 'fixtures') {
        const componentName = currentPath.split('/').pop();
        createStoryForComponentFromFixtures(prefix, componentName, currentFile, fileName, err => {
          if (err) {
            console.error(' - Error: ', err);
          }
        });
      } else {
        searchForFixtures(prefix, currentFile);
      }
    }
  }
};

const checkForStories = function (prefix, componentFolder, componentName) {
  const files = _fsExtra.default.readdirSync(componentFolder);

  let hasStoriesFolder = false;
  let isSingleComponent = false;

  for (const i in files) {
    const fileName = files[i];

    const currentFile = _path.default.join(componentFolder, fileName);

    const stats = _fsExtra.default.statSync(currentFile);

    if (stats.isDirectory()) {
      if (fileName === '_stories') {
        hasStoriesFolder = true;
      }
    } else if (fileName === componentName + '.js') {
      isSingleComponent = true;
    }
  }

  if (!hasStoriesFolder && isSingleComponent) {
    const chapters = [{
      name: 'Default',
      props: {}
    }];
    createStoriesFolder(componentName, componentFolder, err => {
      if (err) {
        console.error('- Error: Unable to create _stories folder', err);
      } else {
        createStoryFile(prefix, componentName, componentFolder, err => {
          if (err) {
            if (err !== 'File exists') {
              return console.error('- Error: Unable to create story file', err);
            }
          }
        });
        createStoryDataFile(componentName, componentFolder, chapters, err => {
          if (err) {
            if (err !== 'File exists') {
              return console.error('- Error: Unable to create story data file', err);
            }
          }
        });
      }
    });
  }
};

var start = function (componentPath, prefix) {
  const components = _fsExtra.default.readdirSync(componentPath);

  for (const i in components) {
    const componentName = components[i];

    const componentFile = _path.default.join(componentPath, componentName);

    const stats = _fsExtra.default.statSync(componentFile);

    if (stats.isDirectory()) {
      searchForFixtures(prefix, componentFile);
      checkForStories(prefix, componentFile, componentName);
    }
  }
};

module.exports = exports.default;