var fs = require('fs')
var path = require('path')
var _ = require('../packages/@yoda/util/_')

var nodeRequire = require

var descriptorFiles = fs.readdirSync(path.join(__dirname, '../runtime/descriptor'))
var api = descriptorFiles
  .filter(it => !it.endsWith('descriptor.js'))
  .map(it => ({
    name: path.basename(it, '.js'),
    descriptor: generate(it)
  }))
  .reduce((accu, it) => {
    if (it.name === 'activity') {
      Object.assign(accu, it.descriptor)
      return accu
    }

    accu.namespaces[_.camelCase(it.name)] = it.descriptor
    return accu
  }, { namespaces: {} })

var makeTime = new Date().toJSON()
var apis = `/**
* @file  yodaos_apis.h  
* @brief The names of api and event. Api and event naming rules: prefix, YODAOSAPI; NS, namespace; MT, method; EV: event. This file is automatically generated, please do not modify it directly.Made at ${makeTime}.
*/
#ifndef YODAOS_APIS_H
#define YODAOS_APIS_H

/**
 * @brief The api names
 */
typedef enum yodaos_api_name{`

var apiContainer = `/**
* @file  yodaos_api_container.h  
* @brief The container of event information and api information. This file is automatically generated, please do not modify it directly.Made at ${makeTime}.
*/
#include "yodaos_api_defines.h"
#include "yodaos_apis.h"

/**
 * @brief the method container,include namespace and method name.
 */
struct yodaos_api_s api_container[] = {`

var evsName = `/**
* @brief The event names
*/
typedef enum yodaos_ev_name{`
var evsContainer = `/**
* @brief the event container,include namespace and event name.
*/
struct yodaos_ev_s ev_container[] = {`

Object.keys(api).forEach((key) => {
  if (key === 'namespaces') {
    let nsObject = api['namespaces']
    Object.keys(nsObject).forEach((nsName) => {
      let tmp = nsObject[nsName]
      if (tmp['methods']) {
        Object.keys(tmp['methods']).forEach((methodsName) => {
          let _enumName = `YODAOSAPI_NS_` + nsName.toUpperCase() + '_MT_' + methodsName.toUpperCase()

          apis += `
    ` + _enumName + ','
          apiContainer += `
    {` + _enumName + `, "` + nsName + `", "` + methodsName + `"},`
        })
      }

      if (tmp['events']) {
        Object.keys(tmp['events']).forEach((evName) => {
          let _evName = `YODAOSAPI_NS_` + nsName.toUpperCase() + '_EV_' + evName.toUpperCase()
          evsName += `
    ` + _evName + ','

          evsContainer += `
    {` + _evName + `, "` + nsName + `", "` + evName + `"},`
        })
      }
    })
  }

  if (key === 'methods') {
    Object.keys(api['methods']).forEach((methodsName) => {
      let _enumName = `YODAOSAPI_NS_GLOBAL_MT_` + methodsName.toUpperCase()

      apis += `
    ` + _enumName + ','
      apiContainer += `
    {` + _enumName + `, "", "` + methodsName + `"},`
    })
  }

  if (key === 'events') {
    Object.keys(api['events']).forEach((evName) => {
      let _evName = `YODAOSAPI_NS_GLOBAL_EV_` + evName.toUpperCase()
      evsName += `
    ` + _evName + ','
      evsContainer += `
    {${_evName}, "", "${evName}"},`
    })
  }
})

apiContainer += `
};
` + evsContainer + `
};`

apis += `
} YODAOS_APINAME;

` + evsName + `
} YODAOS_EVNAME;

#endif`

fs.writeFileSync(path.join(__dirname, '../client/c/include/yodaos_apis.h'), apis)
fs.writeFileSync(path.join(__dirname, '../client/c/include/yodaos_api_container.h'), apiContainer)

function generate (filename) {
  var dirname = path.join(__dirname, '../runtime/descriptor')
  var module = { exports: {} } //eslint-disable-line
  var require = (id) => {  //eslint-disable-line
    if (id === 'logger') {
      return function () { }
    }
    var ret = function () { }
    if (id.startsWith('.')) {
      id = path.join(dirname, id)
    }
    try {
      ret = nodeRequire(id)
    } catch (err) {

    }
    return ret
  }
  var file = fs.readFileSync(path.join(dirname, filename))
  var content = file.toString()
  eval(content)  //eslint-disable-line
  return {
    values: module.exports.values,
    events: module.exports.events,
    methods: module.exports.methods
  }
}
