const xml2js = require("xml2js");

/**
 * Parses XML string into a JavaScript object.
 * @param {string} xml - The XML string to parse.
 * @param {object} logger - The logger instance.
 * @returns {Promise<object>} The parsed XML object.
 * @throws {Error} If XML parsing fails.
 */
const parseXml = async (xml, logger) => {
  try {
    return await xml2js.parseStringPromise(xml, {
      explicitArray: false,
      tagNameProcessors: [xml2js.processors.stripPrefix],
      attrNameProcessors: [xml2js.processors.stripPrefix]
    });
  } catch (err) {
    logger.log("parts-xml-parse-error", "error", null, null, { error: err });
    throw new Error("Invalid XML");
  }
};

/**
 * Recursively strip `xml2js`-style { _: 'value', $: { ... } } nodes into plain strings.
 * @param {*} obj - Parsed XML object
 * @returns {*} Normalized object
 */
const normalizeXmlObject = (obj) => {
  if (Array.isArray(obj)) {
    return obj.map(normalizeXmlObject);
  }

  if (typeof obj === "object" && obj !== null) {
    if (Object.keys(obj).length === 2 && "_" in obj && "$" in obj) {
      return normalizeXmlObject(obj._); // unwrap {_:"value",$:{...}} to just "value"
    }
    if (Object.keys(obj).length === 1 && "_" in obj) {
      return normalizeXmlObject(obj._); // unwrap {_:"value"}
    }

    const normalized = {};
    for (const key in obj) {
      normalized[key] = normalizeXmlObject(obj[key]);
    }
    return normalized;
  }

  return obj;
};

module.exports = {
  parseXml,
  normalizeXmlObject
};
