"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.convert = void 0;var fs = _interopRequireWildcard(require("fs"));
var path = _interopRequireWildcard(require("path"));
var _util = require("util");


var _unified = require("../source/unified");
var _actualCode = require("../actual-code");function _interopRequireWildcard(obj) {if (obj && obj.__esModule) {return obj;} else {var newObj = {};if (obj != null) {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) {var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};if (desc.get || desc.set) {Object.defineProperty(newObj, key, desc);} else {newObj[key] = obj[key];}}}}newObj.default = obj;return newObj;}}


const readFile = (0, _util.promisify)(fs.readFile);
const writeFile = (0, _util.promisify)(fs.writeFile);

const getTime = () => {
  const date = new Date();
  const pad = n => n.toString().padStart(2, '0');
  return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(
  date.getSeconds())
  }`;
};

const actualCodeCliPlugin = opts => () => {
  const transform = async ({
    type,
    subType,
    data,
    hash,
    payload }) =>
  {
    switch (type) {
      case 'log':{
          if (opts.isVerbose) {
            process.stdout.write(`\x1b[36m[LOG]  ${getTime()}\x1b[m: ${data}\n`);
          }
          return null;
        }
      case 'debug':{
          if (opts.isVerbose) {
            process.stdout.write(`\x1b[33m[DEBUG]${getTime()}\x1b[m: ${data}\n`);
          }
          return null;
        }
      case 'event':{
          if (opts.isVerbose) {
            process.stdout.write(
            `\x1b[32m[EVENT]${getTime()}\x1b[m: ${subType}${
            hash ? `.${hash}` : ''
            }${hash === data ? '' : ` ${data}`}\n`);

          }
          return null;
        }
      case 'output':{
          if (subType === 'stdout') {
            process.stdout.write(data.toString());
          } else if (subType === 'stderr') {
            process.stderr.write(data.toString());
          }
          return { type, subType, data, hash };
        }}

  };
  const createOutput = (
  root,
  codeBlocks) =>
  async results => {
    if (results) {
      codeBlocks.reverse().forEach(codeBlock => {
        if (codeBlock.hash in results) {
          const { data } = results[codeBlock.hash].reduce(
          (acc, res) => {
            if (res.type !== 'output') {
              return acc;
            }

            let data = acc.data;
            if (acc.filetype !== res.subType) {
              if (data.length > 0) {
                data += '\n';
              }
              data += `---${res.subType}\n`;
            }
            data += res.data;
            return { filetype: res.subType, data };
          },
          { filetype: '', data: '' });

          const node = {
            type: 'code',
            value: data };

          codeBlock.parent.children = [
          ...codeBlock.parent.children.slice(0, codeBlock.index + 1),
          node,
          ...codeBlock.parent.children.slice(codeBlock.index + 1)];

        }
      });
    }
    return (0, _unified.stringifyMarkdown)(root);
  };
  return {
    name: 'actual-code CLI',
    resultProcessor: async (root, codeBlocks) => {
      return {
        transform,
        output: createOutput(root, codeBlocks) };

    } };

};

const convert = async (filename, opts, outputfile) => {
  filename = path.resolve(filename);
  if (outputfile) {
    outputfile = path.resolve(outputfile);
  }

  const text = (await readFile(filename)).toString();

  // reporter.event('read file', { filename })
  const actualCode = new _actualCode.ActualCode(filename);

  const sandboxOpts = {
    runMode: true };


  actualCode.registerPlugin(actualCodeCliPlugin(opts));

  await actualCode.run(text, sandboxOpts);
  const doc = await actualCode.waitFinished();

  if (outputfile) {
    // reporter.event('write file', { filename: outputfile })
    await writeFile(outputfile, doc);
  }
  return doc;
};exports.convert = convert;