/**
 *
 *    Copyright (c) 2025 Silicon Labs
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * This module provides utilities for parsing conformance data from XML into expressions.
 *
 * @module Validation API: Parse conformance data from XML
 */

const dbEnum = require('../../src-shared/db-enum')
const conformEvaluator = require('./conformance-expression-evaluator')
const env = require('../util/env')

/**
 * Parses conformance from XML data.
 * The conformance could come from features, attributes, commands, or events
 *
 * Call recursive helper function to parse conformance only if the conformance exists.
 * Otherwise, return empty string directly
 *
 * An example of parsing the conformance of 'User' feature:
 *
 * Input operand from xml data:
 * {
 *   "$": {"code": "USR", "name": "User"},
 *   "mandatoryConform": [
 *      { "andTerm": [
 *           {
 *             "condition": [{"$": {"name": "Matter"}}],
 *             "orTerm": [
 *                 { "feature": [
 *                      { "$": {"name": "PIN"}},
 *                      { "$": {"name": "RID"}},
 *                      { "$": {"name": "FGP"}},
 *                      { "$": {"name": "FACE"}}
 *                   ]
 *                 }
 *               ]
 *            }
 *          ]
 *        }
 *    ]
 * }
 *
 * Output conformance string:
 *  "Matter & (PIN | RID | FGP | FACE)"
 *
 * @param {*} operand
 * @returns The conformance string
 */
function parseConformanceFromXML(operand) {
  let hasConformance = Object.keys(operand).some((key) =>
    key.includes('Conform')
  )
  return hasConformance ? parseConformanceRecursively(operand) : ''
}

/**
 * helper function to parse conformance or an operand in conformance recursively
 *
 * The baseLevelTerms variable include terms that can not have nested terms.
 * When they appear, stop recursing and return the name inside directly
 *
 * @param {*} operand
 * @param {*} depth
 * @param {*} parentJoinChar
 * @returns The conformance string.
 */
function parseConformanceRecursively(operand, depth = 0, parentJoinChar = '') {
  if (depth > 200) {
    throw new Error(`Maximum recursion depth exceeded 
      when parsing conformance: ${JSON.stringify(operand)}`)
  }
  const baseLevelTerms = ['feature', 'condition', 'attribute', 'command']
  if (operand.mandatoryConform) {
    let insideTerm = operand.mandatoryConform[0]
    // Recurse further if insideTerm is not empty
    if (insideTerm && Object.keys(insideTerm).toString() != '$') {
      return parseConformanceRecursively(operand.mandatoryConform[0], depth + 1)
    } else {
      return dbEnum.conformanceTag.mandatory
    }
  } else if (operand.optionalConform) {
    let insideTerm = operand.optionalConform[0]
    // check '$' key is not the only key in the object to handle special cases
    // e.g. '<optionalConform choice="a" more="true"/>'
    if (insideTerm && Object.keys(insideTerm).toString() != '$') {
      return `[${parseConformanceRecursively(operand.optionalConform[0], depth + 1)}]`
    } else {
      return dbEnum.conformanceTag.optional
    }
  } else if (operand.otherwiseConform) {
    return Object.entries(operand.otherwiseConform[0])
      .map(([key, value]) =>
        parseConformanceRecursively({ [key]: value }, depth + 1)
      )
      .join(', ')
  } else if (operand.notTerm) {
    // need to surround terms inside a notTerm with '()' if it contains multiple terms
    // e.g. !(A | B) or !(A & B)
    // able to process multiple parallel notTerms, e.g. !A & !B
    return operand.notTerm
      .map((term) => {
        let nt = parseConformanceRecursively(term, depth + 1)
        return nt.includes('&') || nt.includes('|') ? `!(${nt})` : `!${nt}`
      })
      .join(` ${parentJoinChar} `)
  } else if (operand.andTerm || operand.orTerm) {
    // process andTerm and orTerm in the same logic
    // when joining multiple orTerms inside andTerms, we need to
    // surround them with '()', vice versa for andTerms inside orTerms
    // e.g. A & (B | C) or A | (B & C)
    let joinChar = operand.andTerm ? '&' : '|'
    let termKey = operand.andTerm ? 'andTerm' : 'orTerm'
    let oppositeChar = joinChar == '&' ? '|' : '&'
    return Object.entries(operand[termKey][0])
      .map(([key, value]) => {
        if (baseLevelTerms.includes(key)) {
          return value.map((operand) => operand.$.name).join(` ${joinChar} `)
        } else {
          let terms = parseConformanceRecursively(
            { [key]: value },
            depth + 1,
            joinChar
          )
          return terms.includes(oppositeChar) ? `(${terms})` : terms
        }
      })
      .join(` ${joinChar} `)
  } else if (operand.provisionalConform) {
    return dbEnum.conformanceTag.provisional
  } else if (operand.disallowConform) {
    return dbEnum.conformanceTag.disallowed
  } else if (operand.deprecateConform) {
    return dbEnum.conformanceTag.deprecated
  } else if (operand.describedConform) {
    return dbEnum.conformanceTag.described
  } else {
    // reach base level terms, return the name directly
    for (const term of baseLevelTerms) {
      if (operand[term]) {
        return operand[term][0].$.name
      }
    }
    // reaching here means the term is too complex to parse
    return dbEnum.conformanceTag.described
  }
}

/**
 * if optional attribute is defined, return its value
 * if optional attribute is undefined, check if the element conformance is mandatory
 * if both optional attribute and conformance are undefined, return false
 * Optional attribute takes precedence over conformance for backward compatibility on certain elements
 * Log warnings to zap.log if both optional attribute and conformance are defined
 *
 * @param {*} element
 * @param {*} elementType
 * @returns true if the element is optional, false if the element is mandatory
 */
function getOptionalAttributeFromXML(element, elementType) {
  let conformance = parseConformanceFromXML(element)
  if (element.$.optional) {
    if (conformance) {
      env.logWarningToFile(
        `Redundant 'optional' attribute and 'conformance' tag defined for ${elementType}: ${element.$.name}.` +
          " 'optional' takes precedence, but consider removing it as 'conformance' is the recommended format."
      )
    }
    return element.$.optional == 'true'
  } else {
    if (conformance) {
      return !conformEvaluator.checkIfExpressionHasOperand(
        conformance,
        dbEnum.conformanceTag.mandatory
      )
    } else {
      return false
    }
  }
}

exports.parseConformanceFromXML = parseConformanceFromXML
exports.getOptionalAttributeFromXML = getOptionalAttributeFromXML
