

/*
 * This Module exports Edi which contains a fiew helper functions in order to interpret EDI components ans Elements
 * 
 * The Edi write functionnalities are minimalistic and only work for `UNA:+.? '`
 */


 const reSpecialChars = /(['?:+])/g;
 const reTrim = /(\n\s*)|(\s+$)/gm;

 /** Edi
  * this class serves as an Edi writer
  * 
  * before writing a new message, you must call the `.reset` method
  */
 class Edi{
  constructor(){
    this.reset();
  }

  /** reset
   * this method clear the current edifact string and reset the internal state of Edi
   * 
   * it has to be called before any new message.
   */
  reset() {
    this.edifact = "UNA:+.? '";
    this.firstComponent = undefined;
  }

  /** writeSegement
   * write a segment of name `segment` with a number of elements. 
   * if an element is a complex element (= with more than one component),
   * all components should be passed as an array.
   * 
   * If an element must be empty, pass undefined if this is not the last defined element.
   * @param segment {string} the name of the segment (3 UpperCase chars)
   * @param elements {... string | array}
   * 
   * @example
   * const Edi = require('edifact_orders_iso_16033/edi');
   * //..
   * let edi = new Edi();
   * edi.writeSegment('UNB',['UNOC',1],'WS','ESTORE','NOV',['20181001','1255'],'253006',undefined,'ESTORE');
   */
  writeSegment(segment, ...elements){
    this.edifact += segment;
    this.writeElements(elements);
    this.edifact += "'";
  }

  /** for internal use only
  */
  writeElements(elements){
    for (const element of elements){
      this.edifact += '+';
      this.firstComponent = true;
      if (Array.isArray(element)) {
        for (const component of element){
          this.writeComponent(component);
        }
      }
      else {
        this.writeComponent(element);
      }
    }
  }

  /** for internal use only
  */
  writeComponent(component){
    if (!this.firstComponent) {
      this.edifact += ':';
    }
    this.firstComponent = false;
    if (component !== undefined){
      this.edifact += Edi.escape(component.toString());
    }
  }

  /** for internal use only
  */
  static escape(str){
    return str.replace(reSpecialChars,'?$1');
  }

  /** remove the leading,trailing and LF in order to be complient with EDIFACT
  *  EDIFACT strings are multiline in the test only for readability
  */
  static compact(lines){
    return lines.replace(reTrim,'');
  }
 
}


/**return a Date from an edi date str compatible with SQL
 */
Edi.date = function(datestr){
  let d = datestr.substr(0,4)+'-'+datestr.substr(4,2)+'-'+datestr.substr(6,2);
  return d;
}

/**
 * convert dt to an datetime string YYYY-MM-DD HH:MM:SS
 * @param {*} dt can either be an element ['YYYYMMD','HHMM']  or a YYYYMMDDHHMM string
 */
Edi.datetime= function(dt){
  let d;
  if (Array.isArray(dt)){
    d = dt[0].substr(0,4)+'-'+dt[0].substr(4,2)+'-'+dt[0].substr(6,2)+' '+
    dt[1].substr(0,2)+':'+dt[1].substr(2,2)+':00';
  }
  else {
    d = dt.substr(0,4)+'-'+dt.substr(4,2)+'-'+dt.substr(6,2)+' '+ dt.substr(8,2)+':'+dt.substr(10,2)+':00';
  }
  return d;
}

module.exports = Edi;