/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ctype.h>
#include <stdlib.h>
#include <string.h>

#include <cmark.h>

#include "charmony.h"

#define CFC_NEED_BASE_STRUCT_DEF
#include "CFCBase.h"
#include "CFCCHtml.h"
#include "CFCC.h"
#include "CFCClass.h"
#include "CFCDocuComment.h"
#include "CFCDocument.h"
#include "CFCFunction.h"
#include "CFCHierarchy.h"
#include "CFCMethod.h"
#include "CFCParamList.h"
#include "CFCParcel.h"
#include "CFCSymbol.h"
#include "CFCType.h"
#include "CFCUtil.h"
#include "CFCUri.h"
#include "CFCVariable.h"
#include "CFCCallable.h"

#ifndef true
    #define true 1
    #define false 0
#endif

#define UTF8_NDASH "\xE2\x80\x93"

struct CFCCHtml {
    CFCBase base;
    CFCHierarchy *hierarchy;
    char *doc_path;
    char *header;
    char *footer;
    char *index_filename;
};

static const CFCMeta CFCCHTML_META = {
    "Clownfish::CFC::Binding::C::Html",
    sizeof(CFCCHtml),
    (CFCBase_destroy_t)CFCCHtml_destroy
};

static const char header_template[] =
    "<!DOCTYPE html>\n"
    "<html>\n"
    "<head>\n"
    "<meta charset=\"utf-8\">\n"
    "{autogen_header}"
    "<meta name=\"viewport\" content=\"width=device-width\" />\n"
    "<title>{title}</title>\n"
    "<style type=\"text/css\">\n"
    "body {\n"
    "    max-width: 48em;\n"
    "    font: 0.85em/1.4 sans-serif;\n"
    "}\n"
    "a {\n"
    "    color: #23b;\n"
    "}\n"
    "table {\n"
    "    border-collapse: collapse;\n"
    "}\n"
    "td {\n"
    "    padding: 0;\n"
    "}\n"
    "td.label {\n"
    "    padding-right: 2em;\n"
    "    font-weight: bold;\n"
    "}\n"
    "dt {\n"
    "    font-weight: bold;\n"
    "}\n"
    "pre {\n"
    "    border: 1px solid #ccc;\n"
    "    padding: 0.2em 0.4em;\n"
    "    background: #f6f6f6;\n"
    "    font-size: 0.92em;\n"
    "}\n"
    "pre a {\n"
    "    text-decoration: none;\n"
    "}\n"
    "pre, code {\n"
    "    font-family: \"Consolas\", \"Menlo\", monospace;\n"
    "}\n"
    "span.prefix, span.comment {\n"
    "    color: #888;\n"
    "}\n"
    "</style>\n"
    "</head>\n"
    "<body>\n";

static const char footer_template[] =
    "</body>\n"
    "</html>\n"
    "{autogen_footer}";

char*
S_create_index_doc(CFCCHtml *self, CFCClass **classes, CFCDocument **docs);

char*
S_create_standalone_doc(CFCCHtml *self, CFCDocument *doc);

static int
S_compare_class_name(const void *va, const void *vb);

static int
S_compare_doc_path(const void *va, const void *vb);

static char*
S_html_create_name(CFCClass *klass);

static char*
S_html_create_synopsis(CFCClass *klass);

static char*
S_html_create_description(CFCClass *klass);

static char*
S_html_create_functions(CFCClass *klass);

static char*
S_html_create_methods(CFCClass *klass);

static char*
S_html_create_fresh_methods(CFCClass *klass, CFCClass *ancestor);

static char*
S_html_create_func(CFCClass *klass, CFCCallable *func, const char *prefix,
                   const char *short_sym);

static char*
S_html_create_param_list(CFCClass *klass, CFCCallable *func);

static char*
S_html_create_inheritance(CFCClass *klass);

static char*
S_md_to_html(const char *md, CFCClass *klass, int dir_level);

static void
S_transform_doc(cmark_node *node, CFCClass *klass, int dir_level);

static int
S_transform_code_block(cmark_node *node, int found_matching_code_block);

static void
S_transform_link(cmark_node *link, CFCClass *klass, int dir_level);

static char*
S_type_to_html(CFCType *type, const char *sep, CFCClass *doc_class);

static char*
S_cfc_uri_to_url(CFCUri *uri_obj, CFCClass *base, int dir_level);

static char*
S_class_to_url(CFCClass *klass, CFCClass *base, int dir_level);

static char*
S_document_to_url(CFCDocument *doc, CFCClass *base, int dir_level);

static char*
S_relative_url(const char *url, CFCClass *base, int dir_level);

CFCCHtml*
CFCCHtml_new(CFCHierarchy *hierarchy, const char *header, const char *footer) {
    CFCCHtml *self = (CFCCHtml*)CFCBase_allocate(&CFCCHTML_META);
    return CFCCHtml_init(self, hierarchy, header, footer);
}

CFCCHtml*
CFCCHtml_init(CFCCHtml *self, CFCHierarchy *hierarchy, const char *header,
              const char *footer) {
    CFCUTIL_NULL_CHECK(hierarchy);
    CFCUTIL_NULL_CHECK(header);
    CFCUTIL_NULL_CHECK(footer);

    self->hierarchy = (CFCHierarchy*)CFCBase_incref((CFCBase*)hierarchy);

    const char *dest = CFCHierarchy_get_dest(hierarchy);
    self->doc_path
        = CFCUtil_sprintf("%s" CHY_DIR_SEP "share" CHY_DIR_SEP "doc"
                          CHY_DIR_SEP "clownfish", dest);

    char *header_comment = CFCUtil_make_html_comment(header);
    char *footer_comment = CFCUtil_make_html_comment(footer);
    self->header = CFCUtil_global_replace(header_template, "{autogen_header}",
                                          header_comment);
    self->footer = CFCUtil_global_replace(footer_template, "{autogen_footer}",
                                          footer_comment);
    FREEMEM(footer_comment);
    FREEMEM(header_comment);

    return self;
}

void
CFCCHtml_destroy(CFCCHtml *self) {
    CFCBase_decref((CFCBase*)self->hierarchy);
    FREEMEM(self->doc_path);
    FREEMEM(self->header);
    FREEMEM(self->footer);
    FREEMEM(self->index_filename);
    CFCBase_destroy((CFCBase*)self);
}

void
CFCCHtml_write_html_docs(CFCCHtml *self) {
    CFCHierarchy  *hierarchy    = self->hierarchy;
    CFCClass     **ordered      = CFCHierarchy_ordered_classes(hierarchy);
    CFCDocument  **doc_registry = CFCDocument_get_registry();
    const char    *doc_path     = self->doc_path;

    size_t num_classes = 0;
    for (size_t i = 0; ordered[i] != NULL; i++) {
        ++num_classes;
    }

    size_t num_md_docs = 0;
    for (size_t i = 0; doc_registry[i] != NULL; i++) {
        ++num_md_docs;
    }

    // Clone doc registry.
    size_t bytes = (num_md_docs + 1) * sizeof(CFCDocument*);
    CFCDocument **md_docs = (CFCDocument**)MALLOCATE(bytes);
    memcpy(md_docs, doc_registry, bytes);

    qsort(ordered, num_classes, sizeof(*ordered), S_compare_class_name);
    qsort(md_docs, num_md_docs, sizeof(*md_docs), S_compare_doc_path);

    size_t   max_docs  = 1 + num_classes + num_md_docs;
    char   **filenames = (char**)CALLOCATE(max_docs, sizeof(char*));
    char   **html_docs = (char**)CALLOCATE(max_docs, sizeof(char*));
    size_t   num_docs  = 0;

    // Generate HTML docs, but don't write.  That way, if there's an error
    // while generating the pages, we leak memory but don't clutter up the file
    // system.

    char *index_doc = S_create_index_doc(self, ordered, md_docs);
    if (index_doc != NULL) {
        filenames[num_docs] = CFCUtil_strdup(self->index_filename);
        html_docs[num_docs] = index_doc;
        num_docs++;
    }

    for (size_t i = 0; ordered[i] != NULL; i++) {
        CFCClass *klass = ordered[i];
        if (CFCClass_included(klass) || !CFCClass_public(klass)) {
            continue;
        }

        const char *class_name = CFCClass_get_name(klass);
        char *path = CFCUtil_global_replace(class_name, "::", CHY_DIR_SEP);
        filenames[num_docs] = CFCUtil_sprintf("%s.html", path);
        html_docs[num_docs] = CFCCHtml_create_html_doc(self, klass);
        ++num_docs;

        FREEMEM(path);
    }

    for (size_t i = 0; md_docs[i] != NULL; i++) {
        CFCDocument *md_doc = md_docs[i];
        const char *path = CFCDocument_get_path_part(md_doc);
        filenames[num_docs] = CFCUtil_sprintf("%s.html", path);
        html_docs[num_docs] = S_create_standalone_doc(self, md_doc);
        ++num_docs;
    }

    // Write out docs.

    for (size_t i = 0; i < num_docs; ++i) {
        char *filename = filenames[i];
        char *path     = CFCUtil_sprintf("%s" CHY_DIR_SEP "%s", doc_path,
                                         filename);

        // Make path.

        char *dir  = CFCUtil_strdup(path);
        for (size_t j = strlen(dir); j--;) {
            if (dir[j] == CHY_DIR_SEP_CHAR) {
                do {
                    dir[j] = '\0';
                } while (j-- && dir[j] == CHY_DIR_SEP_CHAR);
                break;
            }
        }

        if (dir[0] != '\0' && !CFCUtil_is_dir(dir)) {
            CFCUtil_make_path(dir);
            if (!CFCUtil_is_dir(dir)) {
                CFCUtil_die("Can't make path %s", dir);
            }
        }

        char *html_doc = html_docs[i];
        CFCUtil_write_if_changed(path, html_doc, strlen(html_doc));
        FREEMEM(html_doc);
        FREEMEM(path);
        FREEMEM(filename);
    }

    FREEMEM(html_docs);
    FREEMEM(filenames);
    FREEMEM(ordered);
}

char*
S_create_index_doc(CFCCHtml *self, CFCClass **classes, CFCDocument **docs) {
    CFCParcel **parcels = CFCParcel_all_parcels();

    // Compile standalone document list.

    char *doc_list = CFCUtil_strdup("");

    for (size_t i = 0; docs[i] != NULL; i++) {
        CFCDocument *doc = docs[i];

        const char *path_part = CFCDocument_get_path_part(doc);
        char *url  = CFCUtil_global_replace(path_part, CHY_DIR_SEP, "/");
        char *name = CFCUtil_global_replace(path_part, CHY_DIR_SEP, "::"); 
        doc_list
            = CFCUtil_cat(doc_list, "<li><a href=\"", url, ".html\">",
                          name, "</a></li>\n", NULL);
        FREEMEM(name);
        FREEMEM(url);
    }

    if (doc_list[0] != '\0') {
        const char *pattern =
            "<h2>Documentation</h2>\n"
            "<ul>\n"
            "%s"
            "</ul>\n";
        char *contents = doc_list;
        doc_list = CFCUtil_sprintf(pattern, contents);
        FREEMEM(contents);
    }

    // Compile class lists per parcel.

    char *class_lists    = CFCUtil_strdup("");
    char *parcel_names   = CFCUtil_strdup("");
    char *filename = CFCUtil_strdup("");

    for (size_t i = 0; parcels[i]; i++) {
        CFCParcel *parcel = parcels[i];
        if (CFCParcel_included(parcel)) { continue; }

        const char *prefix      = CFCParcel_get_prefix(parcel);
        const char *parcel_name = CFCParcel_get_name(parcel);

        char *class_list = CFCUtil_strdup("");

        for (size_t i = 0; classes[i] != NULL; i++) {
            CFCClass *klass = classes[i];
            if (strcmp(CFCClass_get_prefix(klass), prefix) != 0
                || !CFCClass_public(klass)
            ) {
                continue;
            }

            const char *class_name = CFCClass_get_name(klass);
            char *url = S_class_to_url(klass, NULL, 0);
            class_list
                = CFCUtil_cat(class_list, "<li><a href=\"", url, "\">",
                              class_name, "</a></li>\n", NULL);
            FREEMEM(url);
        }

        if (class_list[0] != '\0') {
            const char *pattern =
                "<h2>Classes in parcel %s</h2>\n"
                "<ul>\n"
                "%s"
                "</ul>\n";
            char *html = CFCUtil_sprintf(pattern, parcel_name, class_list);
            class_lists = CFCUtil_cat(class_lists, html, NULL);
            FREEMEM(html);

            const char *parcel_name = CFCParcel_get_name(parcel);
            const char *sep = parcel_names[0] == '\0' ? "" : ", ";
            parcel_names = CFCUtil_cat(parcel_names, sep, parcel_name, NULL);

            const char *parcel_prefix = CFCParcel_get_prefix(parcel);
            filename = CFCUtil_cat(filename, parcel_prefix, NULL);
        }

        FREEMEM(class_list);
    }

    // Create doc.

    char *title  = CFCUtil_sprintf("%s " UTF8_NDASH " C API Index",
                                   parcel_names);
    char *header = CFCUtil_global_replace(self->header, "{title}", title);

    const char pattern[] =
        "%s"
        "<h1>%s</h1>\n"
        "%s"
        "%s"
        "%s";
    char *doc
        = CFCUtil_sprintf(pattern, header, title, doc_list, class_lists,
                          self->footer);

    // Create filename

    if (filename[0] == '\0') {
        for (size_t i = 0; parcels[i]; i++) {
            CFCParcel *parcel = parcels[i];
            if (CFCParcel_included(parcel)) { continue; }
            const char *prefix = CFCParcel_get_prefix(parcel);
            filename = CFCUtil_cat(filename, prefix, NULL);
        }
    }

    char *retval = NULL;

    if (filename[0] != '\0') {
        // Removing trailing underscore.
        size_t filename_len = strlen(filename);
        filename[filename_len-1] = '\0';

        // Add .html extension.
        char *base = filename;
        filename = CFCUtil_sprintf("%s.html", base);
        FREEMEM(base);

        retval = doc;
        doc    = NULL;

        FREEMEM(self->index_filename);
        self->index_filename = filename;
        filename             = NULL;
    }

    FREEMEM(doc);
    FREEMEM(header);
    FREEMEM(title);
    FREEMEM(filename);
    FREEMEM(parcel_names);
    FREEMEM(class_lists);
    FREEMEM(doc_list);

    return retval;
}

char*
S_create_standalone_doc(CFCCHtml *self, CFCDocument *doc) {
    const char *path = CFCDocument_get_path_part(doc);
    char *title  = CFCUtil_global_replace(path, CHY_DIR_SEP, "::");
    char *header = CFCUtil_global_replace(self->header, "{title}", title);

    const char *md = CFCDocument_get_contents(doc);
    int dir_level = 0;
    for (size_t i = 0; path[i]; i++) {
        if (path[i] == CHY_DIR_SEP_CHAR) { ++dir_level; }
    }
    char *body = S_md_to_html(md, NULL, dir_level);

    char *html_doc = CFCUtil_sprintf("%s%s%s", header, body, self->footer);

    FREEMEM(body);
    FREEMEM(header);
    FREEMEM(title);
    return html_doc;
}

char*
CFCCHtml_create_html_doc(CFCCHtml *self, CFCClass *klass) {
    const char *class_name     = CFCClass_get_name(klass);
    char *title
        = CFCUtil_sprintf("%s " UTF8_NDASH " C API Documentation", class_name);
    char *header = CFCUtil_global_replace(self->header, "{title}", title);
    char *body = CFCCHtml_create_html_body(self, klass);

    char *html_doc = CFCUtil_sprintf("%s%s%s", header, body, self->footer);

    FREEMEM(body);
    FREEMEM(header);
    FREEMEM(title);
    return html_doc;
}

char*
CFCCHtml_create_html_body(CFCCHtml *self, CFCClass *klass) {
    if (self->index_filename == NULL) {
        // Create index filename by creating index doc.
        CFCClass    **ordered = CFCHierarchy_ordered_classes(self->hierarchy);
        CFCDocument **docs    = CFCDocument_get_registry();
        char *index_doc = S_create_index_doc(self, ordered, docs);
        FREEMEM(index_doc);
        FREEMEM(ordered);

        if (self->index_filename == NULL) {
            CFCUtil_die("Empty hierarchy");
        }
    }

    CFCParcel  *parcel         = CFCClass_get_parcel(klass);
    const char *parcel_name    = CFCParcel_get_name(parcel);
    const char *prefix         = CFCClass_get_prefix(klass);
    const char *PREFIX         = CFCClass_get_PREFIX(klass);
    const char *class_name     = CFCClass_get_name(klass);
    const char *class_nickname = CFCClass_get_nickname(klass);
    const char *class_var      = CFCClass_short_class_var(klass);
    const char *struct_sym     = CFCClass_get_struct_sym(klass);
    const char *include_h      = CFCClass_include_h(klass);

    // Create NAME.
    char *name = S_html_create_name(klass);

    // Create SYNOPSIS.
    char *synopsis = S_html_create_synopsis(klass);

    // Create DESCRIPTION.
    char *description = S_html_create_description(klass);

    // Create CONSTRUCTORS.
    char *functions_html = S_html_create_functions(klass);

    // Create METHODS, possibly including an ABSTRACT METHODS section.
    char *methods_html = S_html_create_methods(klass);

    // Build an INHERITANCE section describing class ancestry.
    char *inheritance = S_html_create_inheritance(klass);

    char *index_url = S_relative_url(self->index_filename, klass, 0);

    // Put it all together.
    const char pattern[] =
        "<h1>%s</h1>\n"
        "<table>\n"
        "<tr>\n"
        "<td class=\"label\">parcel</td>\n"
        "<td><a href=\"%s\">%s</a></td>\n"
        "</tr>\n"
        "<tr>\n"
        "<td class=\"label\">class variable</td>\n"
        "<td><code><span class=\"prefix\">%s</span>%s</code></td>\n"
        "</tr>\n"
        "<tr>\n"
        "<td class=\"label\">struct symbol</td>\n"
        "<td><code><span class=\"prefix\">%s</span>%s</code></td>\n"
        "</tr>\n"
        "<tr>\n"
        "<td class=\"label\">class nickname</td>\n"
        "<td><code><span class=\"prefix\">%s</span>%s</code></td>\n"
        "</tr>\n"
        "<tr>\n"
        "<td class=\"label\">header file</td>\n"
        "<td><code>%s</code></td>\n"
        "</tr>\n"
        "</table>\n"
        "%s"
        "%s"
        "%s"
        "%s"
        "%s"
        "%s";
    char *html_body
        = CFCUtil_sprintf(pattern, class_name, index_url,
                          parcel_name, PREFIX, class_var, prefix, struct_sym,
                          prefix, class_nickname, include_h, name, synopsis,
                          description, functions_html, methods_html,
                          inheritance);

    FREEMEM(index_url);
    FREEMEM(name);
    FREEMEM(synopsis);
    FREEMEM(description);
    FREEMEM(functions_html);
    FREEMEM(methods_html);
    FREEMEM(inheritance);

    return html_body;
}

static int
S_compare_class_name(const void *va, const void *vb) {
    const char *a = CFCClass_get_name(*(CFCClass**)va);
    const char *b = CFCClass_get_name(*(CFCClass**)vb);

    return strcmp(a, b);
}

static int
S_compare_doc_path(const void *va, const void *vb) {
    const char *a = CFCDocument_get_path_part(*(CFCDocument**)va);
    const char *b = CFCDocument_get_path_part(*(CFCDocument**)vb);

    return strcmp(a, b);
}

static char*
S_html_create_name(CFCClass *klass) {
    const char     *class_name = CFCClass_get_name(klass);
    char           *md         = CFCUtil_strdup(class_name);
    CFCDocuComment *docucom    = CFCClass_get_docucomment(klass);

    if (docucom) {
        const char *raw_brief = CFCDocuComment_get_brief(docucom);
        if (raw_brief && raw_brief[0] != '\0') {
            md = CFCUtil_cat(md, " " UTF8_NDASH " ", raw_brief, NULL);
        }
    }

    char *html = S_md_to_html(md, klass, 0);

    const char *format =
        "<h2>Name</h2>\n"
        "%s";
    char *result = CFCUtil_sprintf(format, html);

    FREEMEM(html);
    FREEMEM(md);
    return result;
}

static char*
S_html_create_synopsis(CFCClass *klass) {
    CHY_UNUSED_VAR(klass);
    return CFCUtil_strdup("");
}

static char*
S_html_create_description(CFCClass *klass) {
    CFCDocuComment *docucom = CFCClass_get_docucomment(klass);
    char           *desc    = NULL;

    if (docucom) {
        const char *raw_desc = CFCDocuComment_get_long(docucom);
        if (raw_desc && raw_desc[0] != '\0') {
            desc = S_md_to_html(raw_desc, klass, 0);
        }
    }

    if (!desc) { return CFCUtil_strdup(""); }

    char *result = CFCUtil_sprintf("<h2>Description</h2>\n%s", desc);

    FREEMEM(desc);
    return result;
}

static char*
S_html_create_functions(CFCClass *klass) {
    CFCFunction **functions = CFCClass_functions(klass);
    const char   *prefix    = CFCClass_get_prefix(klass);
    char         *result    = CFCUtil_strdup("");

    for (int func_num = 0; functions[func_num] != NULL; func_num++) {
        CFCFunction *func = functions[func_num];
        if (!CFCFunction_public(func)) { continue; }

        if (result[0] == '\0') {
            result = CFCUtil_cat(result, "<h2>Functions</h2>\n<dl>\n", NULL);
        }

        const char *name = CFCFunction_get_name(func);
        result = CFCUtil_cat(result, "<dt id=\"func_", name, "\">",
                             name, "</dt>\n", NULL);

        char *short_sym = CFCFunction_short_func_sym(func, klass);
        char *func_html = S_html_create_func(klass, (CFCCallable*)func, prefix,
                                             short_sym);
        result = CFCUtil_cat(result, func_html, NULL);
        FREEMEM(func_html);
        FREEMEM(short_sym);
    }

    if (result[0] != '\0') {
        result = CFCUtil_cat(result, "</dl>\n", NULL);
    }

    return result;
}

static char*
S_html_create_methods(CFCClass *klass) {
    char *methods_html  = CFCUtil_strdup("");
    char *result;

    for (CFCClass *ancestor = klass;
         ancestor;
         ancestor = CFCClass_get_parent(ancestor)
    ) {
        const char *class_name = CFCClass_get_name(ancestor);
        // Exclude methods inherited from Clownfish::Obj
        if (ancestor != klass && strcmp(class_name, "Clownfish::Obj") == 0) {
            break;
        }

        char *fresh_html = S_html_create_fresh_methods(klass, ancestor);
        if (fresh_html[0] != '\0') {
            if (ancestor == klass) {
                methods_html = CFCUtil_cat(methods_html, fresh_html, NULL);
            }
            else {
                methods_html
                    = CFCUtil_cat(methods_html, "<h3>Methods inherited from ",
                                  class_name, "</h3>\n", fresh_html, NULL);
            }
        }
        FREEMEM(fresh_html);
    }

    if (methods_html[0] == '\0') {
        result = CFCUtil_strdup("");
    }
    else {
        result = CFCUtil_sprintf("<h2>Methods</h2>\n%s", methods_html);
    }

    FREEMEM(methods_html);
    return result;
}

/** Return HTML for the fresh methods of `ancestor`.
 */
static char*
S_html_create_fresh_methods(CFCClass *klass, CFCClass *ancestor) {
    CFCMethod  **fresh_methods = CFCClass_fresh_methods(klass);
    const char  *prefix        = CFCClass_get_prefix(klass);
    char        *result        = CFCUtil_strdup("");

    for (int meth_num = 0; fresh_methods[meth_num] != NULL; meth_num++) {
        CFCMethod *method = fresh_methods[meth_num];
        if (!CFCMethod_public(method)) {
            continue;
        }

        if (!CFCMethod_is_fresh(method, ancestor)) {
            // The method is implementated in a subclass and already
            // documented.
            continue;
        }

        if (result[0] == '\0') {
            result = CFCUtil_cat(result, "<dl>\n", NULL);
        }

        const char *name = CFCMethod_get_name(method);
        result = CFCUtil_cat(result, "<dt id=\"func_", name, "\">",
                             name, NULL);
        if (CFCMethod_abstract(method)) {
            result = CFCUtil_cat(result,
                    " <span class=\"comment\">(abstract)</span>", NULL);
        }
        result = CFCUtil_cat(result, "</dt>\n", NULL);

        char       *short_sym = CFCMethod_short_method_sym(method, klass);
        char *method_html = S_html_create_func(klass, (CFCCallable*)method,
                                               prefix, short_sym);
        result = CFCUtil_cat(result, method_html, NULL);
        FREEMEM(method_html);
        FREEMEM(short_sym);
    }

    if (result[0] != '\0') {
        result = CFCUtil_cat(result, "</dl>\n", NULL);
    }

    return result;
}

static char*
S_html_create_func(CFCClass *klass, CFCCallable *func, const char *prefix,
                   const char *short_sym) {
    CFCType    *ret_type      = CFCCallable_get_return_type(func);
    char       *ret_html      = S_type_to_html(ret_type, "", klass);
    const char *ret_array     = CFCType_get_array(ret_type);
    const char *ret_array_str = ret_array ? ret_array : "";
    const char *incremented   = "";

    if (CFCType_incremented(ret_type)) {
        incremented = " <span class=\"comment\">// incremented</span>";
    }

    char *param_list = S_html_create_param_list(klass, func);

    const char *pattern =
        "<dd>\n"
        "<pre><code>%s%s%s\n"
        "<span class=\"prefix\">%s</span><strong>%s</strong>%s</code></pre>\n";
    char *result = CFCUtil_sprintf(pattern, ret_html, ret_array_str,
                                   incremented, prefix, short_sym, param_list);

    FREEMEM(param_list);

    // Get documentation, which may be inherited.
    CFCDocuComment *docucomment = CFCCallable_get_docucomment(func);
    if (!docucomment) {
        const char *name = CFCCallable_get_name(func);
        CFCClass *parent = klass;
        while (NULL != (parent = CFCClass_get_parent(parent))) {
            CFCCallable *parent_func
                = (CFCCallable*)CFCClass_method(parent, name);
            if (!parent_func) { break; }
            docucomment = CFCCallable_get_docucomment(parent_func);
            if (docucomment) { break; }
        }
    }

    if (docucomment) {
        // Description
        const char *raw_desc = CFCDocuComment_get_description(docucomment);
        char *desc = S_md_to_html(raw_desc, klass, 0);
        result = CFCUtil_cat(result, desc, NULL);
        FREEMEM(desc);

        // Params
        const char **param_names
            = CFCDocuComment_get_param_names(docucomment);
        const char **param_docs
            = CFCDocuComment_get_param_docs(docucomment);
        if (param_names[0]) {
            result = CFCUtil_cat(result, "<dl>\n", NULL);
            for (size_t i = 0; param_names[i] != NULL; i++) {
                char *doc = S_md_to_html(param_docs[i], klass, 0);
                result = CFCUtil_cat(result, "<dt>", param_names[i],
                                     "</dt>\n<dd>", doc, "</dd>\n",
                                     NULL);
                FREEMEM(doc);
            }
            result = CFCUtil_cat(result, "</dl>\n", NULL);
        }

        // Return value
        const char *retval_doc = CFCDocuComment_get_retval(docucomment);
        if (retval_doc && strlen(retval_doc)) {
            char *md = CFCUtil_sprintf("**Returns:** %s", retval_doc);
            char *html = S_md_to_html(md, klass, 0);
            result = CFCUtil_cat(result, html, NULL);
            FREEMEM(html);
            FREEMEM(md);
        }
    }

    result = CFCUtil_cat(result, "</dd>\n", NULL);

    FREEMEM(ret_html);
    return result;
}

static char*
S_html_create_param_list(CFCClass *klass, CFCCallable *func) {
    CFCParamList  *param_list = CFCCallable_get_param_list(func);
    CFCVariable  **variables  = CFCParamList_get_variables(param_list);

    const char *cfc_class = CFCBase_get_cfc_class((CFCBase*)func);
    int is_method = strcmp(cfc_class, "Clownfish::CFC::Model::Method") == 0;

    if (!variables[0]) {
        return CFCUtil_strdup("(void);\n");
    }

    char *result = CFCUtil_strdup("(\n");

    for (int i = 0; variables[i]; ++i) {
        CFCVariable *variable  = variables[i];
        CFCType     *type      = CFCVariable_get_type(variable);
        const char  *name      = CFCVariable_get_name(variable);
        const char  *array     = CFCType_get_array(type);
        const char  *array_str = array ? array : "";

        char *type_html;
        if (is_method && i == 0) {
            const char *prefix     = CFCClass_get_prefix(klass);
            const char *struct_sym = CFCClass_get_struct_sym(klass);
            const char *pattern    = "<span class=\"prefix\">%s</span>%s *";
            type_html = CFCUtil_sprintf(pattern, prefix, struct_sym);
        }
        else {
            type_html = S_type_to_html(type, " ", klass);
        }

        const char *sep = variables[i+1] ? "," : "";
        const char *decremented = "";

        if (CFCType_decremented(type)) {
            decremented = " <span class=\"comment\">// decremented</span>";
        }

        const char *pattern = "    %s<strong>%s</strong>%s%s%s\n";
        char *param_html = CFCUtil_sprintf(pattern, type_html, name, array_str,
                                           sep, decremented);
        result = CFCUtil_cat(result, param_html, NULL);

        FREEMEM(param_html);
        FREEMEM(type_html);
    }

    result = CFCUtil_cat(result, ");\n", NULL);

    return result;
}

static char*
S_html_create_inheritance(CFCClass *klass) {
    CFCClass *ancestor = CFCClass_get_parent(klass);
    char     *result   = CFCUtil_strdup("");

    if (!ancestor) { return result; }

    const char *class_name = CFCClass_get_name(klass);
    result = CFCUtil_cat(result, "<h2>Inheritance</h2>\n<p>", class_name,
                         NULL);
    while (ancestor) {
        const char *ancestor_name = CFCClass_get_name(ancestor);
        char *ancestor_url = S_class_to_url(ancestor, klass, 0);
        result = CFCUtil_cat(result, " is a <a href=\"", ancestor_url, "\">",
                             ancestor_name, "</a>", NULL);
        FREEMEM(ancestor_url);
        ancestor = CFCClass_get_parent(ancestor);
    }
    result = CFCUtil_cat(result, ".</p>\n", NULL);

    return result;
}

static char*
S_md_to_html(const char *md, CFCClass *klass, int dir_level) {
    int options = CMARK_OPT_SMART
                  | CMARK_OPT_VALIDATE_UTF8;
    cmark_node *doc = cmark_parse_document(md, strlen(md), options);
    S_transform_doc(doc, klass, dir_level);
    char *html = cmark_render_html(doc, CMARK_OPT_SAFE);
    cmark_node_free(doc);

    return html;
}

static void
S_transform_doc(cmark_node *node, CFCClass *klass, int dir_level) {
    int found_matching_code_block = false;
    cmark_iter *iter = cmark_iter_new(node);
    cmark_event_type ev_type;

    while (CMARK_EVENT_DONE != (ev_type = cmark_iter_next(iter))) {
        cmark_node *cur = cmark_iter_get_node(iter);
        cmark_node_type type = cmark_node_get_type(cur);

        switch (type) {
            case CMARK_NODE_CODE_BLOCK:
                found_matching_code_block
                    = S_transform_code_block(cur, found_matching_code_block);
                break;

            case CMARK_NODE_LINK:
                if (ev_type == CMARK_EVENT_EXIT) {
                    S_transform_link(cur, klass, dir_level);
                }
                break;

            default:
                break;
        }
    }

    cmark_iter_free(iter);
}

static int
S_transform_code_block(cmark_node *code_block, int found_matching_code_block) {
    int is_host = CFCMarkdown_code_block_is_host(code_block, "c");

    if (is_host) {
        found_matching_code_block = true;
    }

    if (CFCMarkdown_code_block_is_last(code_block)) {
        if (!found_matching_code_block) {
            cmark_node *warning
                = cmark_node_new(CMARK_NODE_CODE_BLOCK);
            cmark_node_set_literal(warning,
                                   "Code example for C is missing");
            cmark_node_insert_after(code_block, warning);
        }
        else {
            // Reset.
            found_matching_code_block = false;
        }
    }

    if (!is_host) { cmark_node_free(code_block); }

    return found_matching_code_block;
}

static void
S_transform_link(cmark_node *link, CFCClass *doc_class, int dir_level) {
    const char *uri_string = cmark_node_get_url(link);
    if (!uri_string || !CFCUri_is_clownfish_uri(uri_string)) {
        return;
    }

    CFCUri     *uri_obj  = CFCUri_new(uri_string, doc_class);
    CFCUriType  uri_type = CFCUri_get_type(uri_obj);
    char       *url      = S_cfc_uri_to_url(uri_obj, doc_class, dir_level);

    if (uri_type == CFC_URI_NULL || uri_type == CFC_URI_ERROR) {
        // Replace link with text.
        char *link_text = CFCC_link_text(uri_obj);
        cmark_node *text_node = cmark_node_new(CMARK_NODE_TEXT);
        cmark_node_set_literal(text_node, link_text);
        cmark_node_insert_after(link, text_node);
        cmark_node_free(link);
        FREEMEM(link_text);
    }
    else if (url) {
        cmark_node_set_url(link, url);

        if (!cmark_node_first_child(link)) {
            // Empty link text.
            char *link_text = CFCC_link_text(uri_obj);

            if (link_text) {
                cmark_node *text_node = cmark_node_new(CMARK_NODE_TEXT);
                cmark_node_set_literal(text_node, link_text);
                cmark_node_append_child(link, text_node);
                FREEMEM(link_text);
            }
        }
    }
    else {
        // Remove link.
        cmark_node *child = cmark_node_first_child(link);
        while (child) {
            cmark_node *next = cmark_node_next(child);
            cmark_node_insert_before(link, child);
            child = next;
        }
        cmark_node_free(link);
    }

    CFCBase_decref((CFCBase*)uri_obj);
    FREEMEM(url);
}

static char*
S_type_to_html(CFCType *type, const char *sep, CFCClass *doc_class) {
    const char *specifier = CFCType_get_specifier(type);
    char *specifier_html = NULL;

    if (CFCType_is_object(type)) {
        CFCClass   *klass = NULL;

        // Don't link to doc class.
        if (strcmp(specifier, CFCClass_full_struct_sym(doc_class)) != 0) {
            klass = CFCClass_fetch_by_struct_sym(specifier);
            if (!klass) {
                CFCUtil_warn("Class '%s' not found", specifier);
            }
            else if (!CFCClass_public(klass)) {
                CFCUtil_warn("Non-public class '%s' used in public method",
                             specifier);
                klass = NULL;
            }
        }

        const char *underscore = strchr(specifier, '_');
        if (!underscore) {
            CFCUtil_die("Unprefixed object specifier '%s'", specifier);
        }

        size_t      offset     = underscore + 1 - specifier;
        char       *prefix     = CFCUtil_strndup(specifier, offset);
        const char *struct_sym = specifier + offset;

        if (!klass) {
            const char *pattern = "<span class=\"prefix\">%s</span>%s";
            specifier_html = CFCUtil_sprintf(pattern, prefix, struct_sym);
        }
        else {
            char *url = S_class_to_url(klass, doc_class, 0);
            const char *pattern =
                "<span class=\"prefix\">%s</span>"
                "<a href=\"%s\">%s</a>";
            specifier_html = CFCUtil_sprintf(pattern, prefix, url, struct_sym);
            FREEMEM(url);
        }

        FREEMEM(prefix);
    }
    else {
        specifier_html = CFCUtil_strdup(specifier);
    }

    const char *const_str = CFCType_const(type) ? "const " : "";

    int indirection = CFCType_get_indirection(type);
    size_t asterisk_offset = indirection < 10 ? 10 - indirection : 0;
    const char *asterisks = "**********";
    const char *ind_str   = asterisks + asterisk_offset;

    char *html = CFCUtil_sprintf("%s%s%s%s", const_str, specifier_html,
                                 sep, ind_str);

    FREEMEM(specifier_html);
    return html;
}

// Return a relative URL for a CFCUri object.
static char*
S_cfc_uri_to_url(CFCUri *uri_obj, CFCClass *doc_class, int dir_level) {
    char *url = NULL;
    CFCUriType type = CFCUri_get_type(uri_obj);

    switch (type) {
        case CFC_URI_CLASS: {
            CFCClass *klass = CFCUri_get_class(uri_obj);
            url = S_class_to_url(klass, doc_class, dir_level);
            break;
        }

        case CFC_URI_FUNCTION:
        case CFC_URI_METHOD: {
            CFCClass *klass = CFCUri_get_class(uri_obj);
            const char *name = CFCUri_get_callable_name(uri_obj);
            char *class_url = S_class_to_url(klass, doc_class, dir_level);
            url = CFCUtil_sprintf("%s#func_%s", class_url, name);
            FREEMEM(class_url);
            break;
        }

        case CFC_URI_DOCUMENT: {
            CFCDocument *doc = CFCUri_get_document(uri_obj);
            url = S_document_to_url(doc, doc_class, dir_level);
            break;
        }

        default:
            break;
    }

    return url;
}

// Return a relative URL to a class.
static char*
S_class_to_url(CFCClass *klass, CFCClass *base, int dir_level) {
    const char *class_name = CFCClass_get_name(klass);
    char *path    = CFCUtil_global_replace(class_name, "::", CHY_DIR_SEP);
    char *url     = CFCUtil_sprintf("%s.html", path);
    char *rel_url = S_relative_url(url, base, dir_level);

    FREEMEM(url);
    FREEMEM(path);
    return rel_url;
}

// Return a relative URL to a document.
static char*
S_document_to_url(CFCDocument *doc, CFCClass *base, int dir_level) {
    const char *path_part = CFCDocument_get_path_part(doc);
    char *slashy  = CFCUtil_global_replace(path_part, CHY_DIR_SEP, "/");
    char *url     = CFCUtil_sprintf("%s.html", slashy);
    char *rel_url = S_relative_url(url, base, dir_level);

    FREEMEM(url);
    FREEMEM(slashy);
    return rel_url;
}

static char*
S_relative_url(const char *url, CFCClass *base, int dir_level) {
    if (base) {
        const char *base_name = CFCClass_get_name(base);
        for (size_t i = 0; base_name[i]; i++) {
            if (base_name[i] == ':' && base_name[i+1] == ':') {
                dir_level++;
                i++;
            }
        }
    }

    // Create path back to root
    size_t bytes = dir_level * 3;
    char *prefix = (char*)MALLOCATE(bytes + 1);
    for (size_t i = 0; i < bytes; i += 3) {
        memcpy(prefix + i, "../", 3);
    }
    prefix[bytes] = '\0';

    char *rel_url = CFCUtil_sprintf("%s%s", prefix, url);

    FREEMEM(prefix);
    return rel_url;
}

