/* config.c - Generates a nice Parsee config file
 * ============================================================
 * Example of usage(for a blow.hole HS and a xmpp.blow.hole JCP):
 * tools/out/config \
 *      -d '/var/lib/parsee' \
 *      -m 'https://pmedia.blow.hole' \
 *      -H 'blow.hole' \
 *      -s 'The Dark Blowhole shared secret' \
 *      -J 'xmpp.blow.hole'
 * Under CC0, as its a rather useful example of a Parsee tool.
 * See LICENSE for more information about Parsee's licensing. */

#include "common.h"

int
Main(Array *args, HashMap *env)
{
    /* TODO: Not user friendly either. */
    ArgParseState state;
    Uri *api_base;
    char *homeserver = NULL, *jcp = NULL, *jabber = NULL;
    char *data = NULL, *media = NULL, *listen = NULL;
    char *component_as = NULL;
    int flag, code = EXIT_FAILURE;
    int port = 5347;
    size_t lmdb_size = 0;
    size_t max_stanza = 10000;

    listen = "localhost";

    ArgParseStateInit(&state);
    while ((flag = ArgParse(&state, args, "H:J:j:s:d:p:m:l:S:M:")) != -1)
    {
        switch (flag)
        {
            case 'H':
                homeserver = state.optArg;
                break;
            case 's':
                jcp = state.optArg;
                break;
            case 'm':
                Free(media);
                media = StrDuplicate(state.optArg);
                break;
            case 'J':
                jabber = state.optArg;
                break;
            case 'j':
                component_as = state.optArg;
                break;
            case 'd':
                data = state.optArg;
                break;
            case 'l':
                listen = state.optArg;
                break;
            case 'p':
                port = strtol(state.optArg, NULL, 10);
                break;
            case 'S':
                lmdb_size = strtol(state.optArg, NULL, 10) * 1024 * 1024;
                break;
            case 'M':
                max_stanza = strtol(state.optArg, NULL, 10);
                if (max_stanza < 10000)
                {
                    max_stanza = 10000;
                }
        }
    }

    api_base = DelegateServer(homeserver);
    if (!api_base || !jcp || !jabber || !data || !listen)
    {
        Log(LOG_ERR,
            "Usage: %s "
                "-d [Database directory] "
                "-m <Base URL for media files>"
                "-H [matrixserv.fed] "
                "-s [XMPP shared secret] "
                "-l [Host/IP to listen as] "
                "-p [XMPP component port=5347] "
                "-J [parsee.xmppserver.ex]", 
                "-M [max stanza size>=10000]", 
                "-S [LMDB size]", 
                ArrayGet(args, 0)
        );
        goto end;
    }
    if (!media)
    {
        char *s_port = StrInt(port);
        media = StrConcat(4, "http://", listen, ":", s_port);
        Free(s_port);
    }

    {
        HashMap *json = HashMapCreate();
        Stream *file = StreamOpen("parsee.json", "w");
        char *as_token, *hs_token;

        as_token = StrRandom(32);
        hs_token = StrRandom(32);

        UtilMkdir(data, 0755);

        JsonSet(json, JsonValueString(data), 1, "db");
        JsonSet(json, JsonValueInteger(lmdb_size), 1, "db_size");

        JsonSet(json, JsonValueString(homeserver), 1, "hs_base");
        JsonSet(json, JsonValueString(api_base->host), 1, "hs_host");
        JsonSet(json, JsonValueInteger(api_base->port), 1, "hs_port");

        JsonSet(json, JsonValueString(as_token), 1, "as_token");
        JsonSet(json, JsonValueString(hs_token), 1, "hs_token");

        JsonSet(json, JsonValueString("_p_"), 1, "namespace");
        JsonSet(json, JsonValueString("_parsee"), 1, "sender");
        JsonSet(json, JsonValueInteger(7642), 1, "port");

        JsonSet(json, JsonValueString(jabber), 1, "component_host");
        JsonSet(json, JsonValueInteger(port), 1, "component_port");
        JsonSet(json, JsonValueInteger(max_stanza), 1, "max_stanza_size");

        JsonSet(json, JsonValueString(jcp), 1, "shared_secret");

        JsonSet(json, JsonValueString(media), 1, "media_base");
        JsonSet(json, JsonValueString(listen), 1, "listen_as");
        JsonSet(json, JsonValueString(component_as), 1, "component_addr");

        JsonEncode(json, file, JSON_PRETTY);
        StreamFlush(file);
        StreamClose(file);

        Log(LOG_INFO, "AS token=%s", as_token);
        Log(LOG_INFO, "HS token=%s", hs_token);
        Free(as_token);
        Free(hs_token);

        JsonFree(json);
    }

    code = EXIT_SUCCESS;
end:
    UriFree(api_base);
    Free(media);
    (void) env;
    return code;
}