import { __require as requireFillRange } from '../../../../fill-range@7.1.1/node_modules/fill-range/index.mjs';
import { __require as requireStringify } from './stringify.mjs';
import { __require as requireUtils } from './utils.mjs';

var expand_1;
var hasRequiredExpand;
function requireExpand() {
  if (hasRequiredExpand) return expand_1;
  hasRequiredExpand = 1;
  const fill = requireFillRange();
  const stringify = requireStringify();
  const utils = requireUtils();
  const append = (queue = '', stash = '', enclose = false) => {
    const result = [];
    queue = [].concat(queue);
    stash = [].concat(stash);
    if (!stash.length) return queue;
    if (!queue.length) {
      return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash;
    }
    for (const item of queue) {
      if (Array.isArray(item)) {
        for (const value of item) {
          result.push(append(value, stash, enclose));
        }
      } else {
        for (let ele of stash) {
          if (enclose === true && typeof ele === 'string') ele = `{${ele}}`;
          result.push(Array.isArray(ele) ? append(item, ele, enclose) : item + ele);
        }
      }
    }
    return utils.flatten(result);
  };
  const expand = (ast, options = {}) => {
    const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit;
    const walk = (node, parent = {}) => {
      node.queue = [];
      let p = parent;
      let q = parent.queue;
      while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
        p = p.parent;
        q = p.queue;
      }
      if (node.invalid || node.dollar) {
        q.push(append(q.pop(), stringify(node, options)));
        return;
      }
      if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
        q.push(append(q.pop(), ['{}']));
        return;
      }
      if (node.nodes && node.ranges > 0) {
        const args = utils.reduce(node.nodes);
        if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
          throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
        }
        let range = fill(...args, options);
        if (range.length === 0) {
          range = stringify(node, options);
        }
        q.push(append(q.pop(), range));
        node.nodes = [];
        return;
      }
      const enclose = utils.encloseBrace(node);
      let queue = node.queue;
      let block = node;
      while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
        block = block.parent;
        queue = block.queue;
      }
      for (let i = 0; i < node.nodes.length; i++) {
        const child = node.nodes[i];
        if (child.type === 'comma' && node.type === 'brace') {
          if (i === 1) queue.push('');
          queue.push('');
          continue;
        }
        if (child.type === 'close') {
          q.push(append(q.pop(), queue, enclose));
          continue;
        }
        if (child.value && child.type !== 'open') {
          queue.push(append(queue.pop(), child.value));
          continue;
        }
        if (child.nodes) {
          walk(child, node);
        }
      }
      return queue;
    };
    return utils.flatten(walk(ast));
  };
  expand_1 = expand;
  return expand_1;
}

export { requireExpand as __require };
