#!/usr/bin/env bash

if [[ "${USERNAME}" == "" ]] || [[ "${GITHUB_ACCESS_TOKEN}" == "" ]]; then
    echo "You must have set a GitHub username & access token environment variable. Like export USERNAME=YOUR_USERNAME; export GITHUB_ACCESS_TOKEN=YOUR_ACCESS_TOKEN";
    exit 1
fi

output=$1
rm -f $output
DOCBRANCH=$2
header="Authorization: token ${GITHUB_ACCESS_TOKEN}"
# Get total number of repository pages in foglamp org.
foglampRepoPagesCount=$(curl -sI https://api.github.com/orgs/foglamp/repos | grep -oP '\d+(?=>; rel="last")')
foglampRepos=$(curl -H "$header" -sX GET https://api.github.com/orgs/foglamp/repos\?page=[1-$foglampRepoPagesCount])
foglampRepos="$(echo $foglampRepos | sed 's/\] \[/,/g')"
fetchTopicReposPyScript='
import json,sys;\
repos=json.load(sys.stdin);\
fRepos = [r["name"] for r in repos["items"]];\
print("\n".join(fRepos));
'
foglamp_wip_repos=$(curl -sX GET -H "$header" -H "Accept: application/vnd.github.mercy-preview+json" https://api.github.com/search/repositories?q=topic:wip+org:foglamp)
foglamp_poc_repos=$(curl -sX GET -H "$header" -H "Accept: application/vnd.github.mercy-preview+json" https://api.github.com/search/repositories?q=topic:poc+org:foglamp)
foglamp_internal_repos=$(curl -sX GET -H "$header" -H "Accept: application/vnd.github.mercy-preview+json" https://api.github.com/search/repositories?q=topic:internal+org:foglamp)
foglamp_obsolete_repos=$(curl -sX GET -H "$header" -H "Accept: application/vnd.github.mercy-preview+json" https://api.github.com/search/repositories?q=topic:obsolete+org:foglamp)
foglamp_wip_repos_name=$(echo ${foglamp_wip_repos} | python3 -c "$fetchTopicReposPyScript" | sort -f)
foglamp_poc_repos_name=$(echo ${foglamp_poc_repos} | python3 -c "$fetchTopicReposPyScript" | sort -f)
foglamp_internal_repos_name=$(echo ${foglamp_internal_repos} | python3 -c "$fetchTopicReposPyScript" | sort -f)
foglamp_obsolete_repos_name=$(echo ${foglamp_obsolete_repos} | python3 -c "$fetchTopicReposPyScript" | sort -f)
export EXCLUDE_FOGLAMP_TOPIC_REPOSITORIES=$(echo ${foglamp_wip_repos_name} ${foglamp_poc_repos_name} ${foglamp_internal_repos_name} ${foglamp_obsolete_repos_name} | sort -f)
echo "EXCLUDED FOGLAMP TOPIC REPOS LIST: $EXCLUDE_FOGLAMP_TOPIC_REPOSITORIES"
fetchFogLAMPReposPyScript='
import os,json,sys;\
repos=json.load(sys.stdin);\
exclude_topic_packages=os.environ["EXCLUDE_FOGLAMP_TOPIC_REPOSITORIES"];\
all_repos = [r["name"] for r in repos if r["archived"] is False];\
fRepos = list(set(all_repos) - set(exclude_topic_packages.split()));\
print("\n".join(fRepos));
'
REPOS=$(echo ${foglampRepos} | python3 -c "$fetchFogLAMPReposPyScript" | sort -f)
INBUILT_PLUGINS="foglamp-north-OMF foglamp-rule-Threshold foglamp-rule-DataAvailability"
REPOSITORIES=$(echo ${REPOS} ${INBUILT_PLUGINS} | xargs -n1 | sort -f | xargs)
echo "REPOSITORIES LIST: "${REPOSITORIES}

# Clean out any old keywords left behind
if [[ -d /tmp/keywords ]]; then
    rm -rf /tmp/keywords
fi

# Create the list header for a new keyword file
function keyword_header {
    keyfile="$1"
    title=$2
    echo ".. list-table:: ${title}" >> "$keyfile"
    echo "    :widths: 20 50" >> "$keyfile"
    echo "    :header-rows: 1" >> "$keyfile"
    echo "" >> "$keyfile"
    echo "    * - Name" >> "$keyfile"
    echo "      - Description" >> "$keyfile"
}

# Create the table of plugins by type. Also generate a set of keyword grouped
# tables in files stored in /tmp/keywords/{plugin type}
function table {
    list="$1"
    title=$2
    tableType=$3
    echo ".. list-table:: ${title}" >> "$output"
    echo "    :widths: 20 50" >> "$output"
    echo "    :header-rows: 1" >> "$output"
    echo "" >> "$output"
    echo "    * - Name" >> "$output"
    echo "      - Description" >> "$output"
    for repo in ${list}
    do
        type=$(echo "${repo}" | sed -e 's/foglamp-//' -e 's/-.*//')
        name=$(echo "${repo}" | sed -e 's/foglamp-//' -e "s/${type}-//")
        if [[ ${type} = "$tableType" ]]; then
            if grep -q "$repo" <<< "$INBUILT_PLUGINS"; then
                if [[ $repo == "foglamp-north-OMF" ]]; then
                    echo "    * - \`omf <"plugins/foglamp-north-OMF/index.html">\`__" >> "$output"
                    echo "      - Send data to OSIsoft PI Server, Edge Data Store or OSIsoft Cloud Services" >> "$output"
                    keyword=OMF
                    mkdir -p "/tmp/keywords/{$type}"
                    keyfile="/tmp/keywords/{$type}/${keyword}"
                    if [[ ! -f "${keyfile}" ]]; then
                        keyword_header "$keyfile" "$title"
                    fi
                    if [[ -f ${repo}/docs/index.rst ]]; then
                        echo "    * - \`$name <"plugins/foglamp-north-OMF/index.html">\`__" >> "$keyfile"
                    else
                        echo "    * - ${name}" >> "${keyfile}"
                    fi
                    echo "      - ${description}" >> "${keyfile}"
                elif [[ $repo == "foglamp-rule-DataAvailability" ]]; then
                    echo "    * - \`data-availability <"plugins/foglamp-rule-DataAvailability/index.html">\`__" >> "$output"
                    echo "      - Triggers every time when it receives data that matches an asset code or audit code those given in the configuration" >> "$output"
                elif [[ $repo == "foglamp-rule-Threshold" ]]; then
                    echo "    * - \`threshold <"plugins/foglamp-rule-Threshold/index.html">\`__" >> "$output"
                    echo "      - Detect the value of a data point within an asset going above or below a set threshold" >> "$output"
                fi
                else
                    rm -rf ${repo}
                    git clone https://${USERNAME}:${GITHUB_ACCESS_TOKEN}@github.com/foglamp/${repo}.git --branch ${DOCBRANCH} >/dev/null 2>&1
                    is_branch_exists=$?
                    if [[ ${is_branch_exists} -eq 0 ]]; then
                        description=$(echo "$foglampRepos" | python3 -c 'import json,sys;repos=json.load(sys.stdin);fRepo = [r for r in repos if r["name"] == "'"${repo}"'" ];print(fRepo[0]["description"])')
                        if [[ "${description}" = "None" ]]; then description="A ${name} ${type} plugin"; fi
                        # cloned directory replaced with installed directory name which is defined in Package file for each repo
                        installed_plugin_dir_name=$(cat ${repo}/Package | grep plugin_install_dirname= | sed -e "s/plugin_install_dirname=//g")
                        if [[ $installed_plugin_dir_name == "\${plugin_name}" ]]; then
                            installed_plugin_dir_name=$(cat ${repo}/Package | grep plugin_name= | sed -e "s/plugin_name=//g")
                        fi
                        old_plugin_name=$(echo ${repo} | cut -d '-' -f3-)
                        new_plugin_name=$(echo ${repo/$old_plugin_name/$installed_plugin_dir_name})
                        # Only link when doc exists in plugins directory
                        if [[ -d ${repo}/docs && -f ${repo}/docs/index.rst ]]; then
                            echo "    * - \`$name <"plugins/$new_plugin_name/index.html">\`__" >> "$output"
                        else
                            echo "    * - ${name}" >> "$output"
                        fi
                        echo "      - ${description}" >> "$output"
                        # Now do the keywords
                        if [[ -d ${repo}/docs && -f ${repo}/docs/keywords ]]; then
                            mkdir -p "/tmp/keywords/${type}"
                            keywords=`sed -e 's/ /%20/g' -e 's/,/ /g' < ${repo}/docs/keywords`
                            for word in $keywords
                            do
                                keyword=$(echo $word | sed -e 's/%20/ /g')
                                keyfile="/tmp/keywords/${type}/${keyword}"
                                if [[ ! -f "${keyfile}" ]]; then
                                    keyword_header "$keyfile" "$title"
                                fi
                                if [[ -f ${repo}/docs/index.rst ]]; then
                                    echo "    * - \`$name <"plugins/$new_plugin_name/index.html">\`__" >> "$keyfile"
                                else
                                    echo "    * - ${name}" >> "${keyfile}"
                                fi
                                echo "      - ${description}" >> "${keyfile}"
                            done
                        fi
                    fi
                    rm -rf ${repo}
            fi
        fi
    done
}

# For a given plugin type collect the keyword files from the tmp
# directory and create the section in the Plugins documentation page
function add_keywords {
    type="$1"
    pluginType="$2"
    find /tmp/keywords/${type} -type f -print0 | while IFS= read -r -d '' file; do
        keyword=$(basename "$file")
        if [[ -f "keywords/${keyword}" ]]; then
            # Use the keyword override header file
            cat "keywords/${keyword}" >> ${output}
        else
            # No override header for this keyword, create a default
            heading="${keyword} Plugins"
            echo $heading >> $output
            echo $heading | sed -e 's/[A-Za-z0-9 ]/^/g' >> $output
        fi
        echo >> $output
        # Add in the table
        cat "${file}" >> $output
        echo >> $output
    done
}

cat >> $output << EOF1
FogLAMP Plugins
==============

The following set of plugins are available for FogLAMP. These plugins
extend the functionality by adding new sources of data, new destinations,
processing filters that can enhance or modify the data, rules for
notification delivery and notification delivery mechanisms.

EOF1
cat >>$output << EOF2
South Plugins
-------------

South plugins add new ways to get data into FogLAMP, a number of south
plugins are available ready built or users may add new south plugins of
their own by writing them in Python or C/C++.

EOF2
table "$REPOSITORIES" "FogLAMP South Plugins" south
cat >>$output << EOF3

North Plugins
-------------

North plugins add new destinations to which data may be sent by FogLAMP. A
number of north plugins are available ready built or users may add new
north plugins of their own by writing them in Python or C/C++.

EOF3
table "$REPOSITORIES" "FogLAMP North Plugins" north
cat >>$output << EOF4

Filter Plugins
--------------

Filter plugins add new ways in which data may be modified, enhanced
or cleaned as part of the ingress via a south service or egress to a
destination system. A number of north plugins are available ready built
or users may add new north plugins of their own by writing them in Python
or C/C++.

It is also possible, using particular filters, to supply expressions
or script snippets that can operate on the data as well. This provides a
simple way to process the data in FogLAMP as it is read from devices or
written to destination systems.

EOF4
table "$REPOSITORIES" "FogLAMP Filter Plugins" filter
cat >>$output << EOF5

Notification Rule Plugins
-------------------------

Notification rule plugins provide the logic that is used by the
notification service to determine if a condition has been met that should
trigger or clear that condition and hence send a notification. A number of
notification plugins are available as standard, however as with any plugin the
user is able to write new plugins in Python or C/C++ to extend the set of
notification rules.

EOF5
table "$REPOSITORIES" "FogLAMP Notification Rule Plugins" rule
cat >>$output << EOF6

Notification Delivery Plugins
-----------------------------

Notification delivery plugins provide the mechanisms to deliver the
notification messages to the systems that will receive them.  A number
of notification delivery plugins are available as standard, however as
with any plugin the user is able to write new plugins in Python or C/C++
to extend the set of notification deliveries.

EOF6
table "$REPOSITORIES" "FogLAMP Notification Delivery Plugins" notify

cat >>$output << EOF7

Plugins Organized by Category
-----------------------------

South
~~~~~

The following tables categorize the south plugins.

EOF7
add_keywords south "South"

cat >>$output << EOF8

North
~~~~~

The following tables categorize the north plugins.

EOF8
add_keywords north "North"

cat >>$output << EOF9

Filters
~~~~~~~

The following tables categorize the filter plugins.

EOF9
add_keywords filter "Filter"

# TODO: Add notification based plugins grouping here

# Clean out any old keywords left behind
if [[ -d /tmp/keywords ]]; then
    rm -rf /tmp/keywords
fi
