"use strict";

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _dataTypes = _interopRequireWildcard(require("./dataTypes"));

var _objectUtils = require("./objectUtils");

var _this = void 0;

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

var compileClassNames = function compileClassNames() {
  var processedClassNameList = [];

  for (var index = 0; index < arguments.length; index++) {
    var classInfo = index < 0 || arguments.length <= index ? undefined : arguments[index];

    if (!classInfo) {
      continue;
    }

    if ((0, _dataTypes.isDataTypeOf)(classInfo, _dataTypes["default"].string) || (0, _dataTypes.isDataTypeOf)(classInfo, _dataTypes["default"].number)) {
      processedClassNameList.push(_this && _this[classInfo] || classInfo);
    } else if ((0, _dataTypes.isDataTypeOf)(classInfo, _dataTypes["default"].array)) {
      processedClassNameList.push(compileClassNames.apply(_this, classInfo));
    } else if ((0, _dataTypes.isDataTypeOf)(classInfo, _dataTypes["default"].object)) {
      if ((0, _objectUtils.isToStringReferenceEqual)(classInfo)) {
        for (var property in classInfo) {
          if (_objectUtils.hasOwnProperty.call(classInfo, property) && classInfo[property]) {
            processedClassNameList.push(_this && _this[property] || property);
          }
        }
      } else {
        processedClassNameList.push(classInfo.toString());
      }
    }
  }

  return processedClassNameList.join(' ');
};

var _default = compileClassNames; //18-Nov-2021 code review changes updated.

/*
>>>>>>>>>>Code Review Suggestion Starts >>>>>>
let hasOwn = {}.hasOwnProperty;

Accounting readability, please change this to Object.hasOwnProperty

---
const compileClassNames = (...props)=>{
Please check the alternate term - collate -> collateClassNames -> Collect and Combine the classnames.
---

for (let i = 0; i < props.length; i++) {

    Please try to to stick with functional programming. Again for the readability perspective.
    Also, please stick with naming conventions for variables (i -> index).

---
if (argType === 'string' || argType === 'number') {
          classes.push(this && this[arg] || arg);
      } else if (Array.isArray(arg)) {
          classes.push(compileClassNames.apply(this, arg));
      } else if (argType === 'object') {
          if (arg.toString === Object.prototype.toString) {
              for (let key in arg) {
                  if (hasOwn.call(arg, key) && arg[key]) {
                      classes.push(this && this[key] || key);
                  }
              }
          } else {
              classes.push(arg.toString());
          }
      }
    }
In this code block, pushing up the array,object checks before string || number will be easy to follow up as it clarifies about the reursive call, its context.
Please check the possibility of avoiding the usage of 'this' statement due to its complexity in understanding the concept.

---
Please write a functional method for the below line for easier understanding 
  
if (arg.toString === Object.prototype.toString) {

---

Adding dedicated method to get the datatype of variables will help to stick on the SRP.
---
Check the possibility of providing platform to extend the algorithm works for other data structures like Map, WeakMap,etc..

>>>>>>> Code Review Suggestion Ends >>>>>>>>>>>>>>>>
*/

/*

>>>>>> Alternative Implementation Starts >>>>>>>>>>>>>>>> 

let boundHasOwnMethod = Object.hasOwnProperty;

 const collateClassNames = (...classinfoList) =>{
     let processedClassNameList = [];
     classinfoList.forEach( ( classInfo,index )=>{
         if(!classInfo)
         {
            // continue the next iteration
             return;
         }
         let dataTypeofClassInfo = getDataType(classInfo);
         if (dataTypeofClassInfo === 'string' || dataTypeofClassInfo === 'number')
         {
             processedClassNameList.push(classInfo);
         }
         else if(dataTypeofClassInfo === 'array')
         {
             processedClassNameList.push(collateClassNames(...classInfo));
         }
         else if(dataTypeofClassInfo === 'object')
         {
             for (let property in classInfo) {
                  if (boundHasOwnMethod.call(classInfo,property ) && classInfo[property]) {
                      processedClassNameList.push(property);
                  }
              }
         }
        

     });
     const joinClassNames = processedClassNameList.join(' ');
    return joinClassNames;

 }

 const getDataType = (data)=>{
    let dataTypeofClassInfo = typeof data;
    let isArrayDataType = Array.isArray(data) === true;
    if(isArrayDataType)
    {
        return 'array';
    }
    else 
    {
        return dataTypeofClassInfo;
    }
   
 };

>>>>>>>>>>>>>>>> Alternative Implementation Ends>>>>>>>>>>>>>> 
*/

exports["default"] = _default;