<template>
  <div :id="name">
    <h3>{{ name || '@q42/q-cms-components' }}</h3>
    <ul>
      <template v-for="(fn, fnName) in module">
        <li :key="fnName" v-if="fn.docs && fnName[0].toLowerCase() == fnName[0]">
          <code>{{ fnName }}{{ header(fn) }}</code>
          <div v-html="fn.docs"></div>
        </li>
      </template>
    </ul>
    <ul>
      <template v-for="(cls, clsName) in module">
        <li :key="clsName" 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)" :key="propName" :class="propName">
                <code>{{ propName }}{{ header(prop) }}</code> <span v-html="cls[propName + 'Docs']"></span>
              </li>
            </ul>
          </div>
        </li>
      </template>
    </ul>
    <p>
      <code>
        import {
        <template v-for="(val, name) in module">
          <span v-if="val.docs" :key="name" class="name">{{ name }}</span>
        </template>
        } from '@q42/q-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>
