"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.convertObjectToStringGen = convertObjectToStringGen;
exports.removeKeysFromObject = removeKeysFromObject;

function objectPathMatcher(currentKey, objHierarchy = [], keysToBeRemoved = []) {
  const objPathKey = objHierarchy.length > 0 ? `${objHierarchy.join('.')}.${currentKey}` : currentKey;
  return keysToBeRemoved.some(key => {
    const isWildPath = /^\*/.test(key);

    if (isWildPath) {
      const newKey = key.replace(/\*\.?/, '');
      return objPathKey.includes(newKey);
    }

    return key === objPathKey;
  });
}
/*
    1) *.keyTobeRemoved -> means match every object path, this key will be removed
    2) keyToBeremoved -> means root object key
    3) nestedPath.keyToBeRemoved -> means only that nested path key
    4) don't need to account for array iteration, just object key path is enough in the key to be removed.
*/


function removeKeysFromObject(obj, keysToBeRemoved, prevKeys = []) {
  if (Array.isArray(obj)) {
    return obj.map(item => removeKeysFromObject(item, keysToBeRemoved, prevKeys));
  }

  if (obj && typeof obj === 'object') {
    const filteredKeyObject = {};
    const ObjectKeys = Object.keys(obj);

    for (const objectKey of ObjectKeys) {
      const isKeyToBeRemoved = objectPathMatcher(objectKey, prevKeys, keysToBeRemoved);

      if (!isKeyToBeRemoved) {
        filteredKeyObject[objectKey] = removeKeysFromObject(obj[objectKey], keysToBeRemoved, [...prevKeys, objectKey]);
      }
    }

    return filteredKeyObject;
  }

  return obj;
}

function* convertObjectToStringGen(obj) {
  if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || obj === null) {
    yield JSON.stringify(obj);
  } else if (Array.isArray(obj)) {
    yield '[';
    let isFirst = true;

    for (let item of obj) {
      if (item === undefined) {
        item = null;
      }

      yield `${isFirst ? '' : ','}`;
      yield* convertObjectToStringGen(item);
      isFirst = false;
    }

    yield ']';
  } else {
    yield '{';
    let isFirst = true;
    const entries = Object.entries(obj);

    for (const [itemKey, itemValue] of entries) {
      if (itemValue === undefined) {
        continue;
      }

      yield `${isFirst ? '' : ','}${JSON.stringify(itemKey)}: `;
      yield* convertObjectToStringGen(itemValue);
      isFirst = false;
    }

    yield '}';
  }
}