<template>
  <div :id="name">
    <h3>{{name || 'q42-cms-components'}}</h3>
    <ul>
      <li v-for="(fn, fnName) in module" v-if="fn.docs && fnName[0].toLowerCase() == fnName[0]">
        <code>{{fnName}}{{header(fn)}}</code> <div v-html="fn.docs"></div>
      </li>
    </ul>
    <ul>
      <li v-for="(cls, clsName) in module" v-if="cls.docs && clsName[0].toUpperCase() == clsName[0]">
        <code>{{clsName}}{{header(cls)}}</code> <div v-html="cls.docs"></div>
        <div v-if="hasProperties(cls)"><b>Methods &amp; properties</b>
          <ul>
            <li v-for="(prop, propName) in properties(cls)">
              <code>{{propName}}{{header(prop)}}</code> <span v-html="cls[propName + 'Docs']"></span>
            </li>
          </ul>
        </div>
      </li>
    </ul>
    <p><code>import {
      <span class="name" v-for="(val, name) in module" v-if="val.docs">{{name}}</span>
    } from 'q42-cms-components{{path}}'</code></p>
  </div>
</template>

<style scoped>
h3 {
  margin-top: 1em;
}
p {
  margin-bottom: 0.5em;
}
span.name + span.name::before {
  content: ', ';
}
</style>

<script>
export default {
  docs: `Genereert documentatie voor een EcmaScript module.`,
  props: {
    path: {
      type: String,
      required: true,
      docs: `Pad incl. bestandsnaam van module.`
    },
    module: {
      required: true,
      docs: `De te documenteren module.`
    }
  },
  computed: {
    name() {
      return this.path.split('/').pop();
    }
  },
  methods: {
    body(fn) {
      return fn.toString().replace(/function [^{]*\{\s*return\s*/, '').replace(/;?\s*}/, '');
    },
    header(fn) {
      return fn.toString().replace(/[^(]*/, '').replace(/\s*\{[^]*/, '');
    },
    properties(cls) {
      var result = {};
      Object.getOwnPropertyNames(cls.prototype).map(name => {
        if (!cls[name + 'Docs']) return;
        try {
          result[name] = cls.prototype[name];
        } catch(e) {
          result[name] = "";
        }
      });
      return result;
    },
    hasProperties(cls) {
      return Object.getOwnPropertyNames(this.properties(cls)).length > 0;
    },
    camel2dash(propName) {
      return propName.replace(/[A-Z]/g, c => '-' + c.toLowerCase());
    }
  }
}
</script>
