/*!
 * \file netopeerguid.c
 * \brief NetopeerGUI daemon
 * \author Tomas Cejka <cejkat@cesnet.cz>
 * \author Radek Krejci <rkrejci@cesnet.cz>
 * \author Michal Vasko <mvasko@cesnet.cz>
 * \date 2011
 * \date 2012
 * \date 2013
 * \date 2015
 */
/*
 * Copyright (C) 2011-2015 CESNET
 *
 * LICENSE TERMS
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name of the Company nor the names of its contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * ALTERNATIVELY, provided that this notice is retained in full, this
 * product may be distributed under the terms of the GNU General Public
 * License (GPL) version 2 or later, in which case the provisions
 * of the GPL apply INSTEAD OF those given above.
 *
 * This software is provided ``as is'', and any express or implied
 * warranties, including, but not limited to, the implied warranties of
 * merchantability and fitness for a particular purpose are disclaimed.
 * In no event shall the company or contributors be liable for any
 * direct, indirect, incidental, special, exemplary, or consequential
 * damages (including, but not limited to, procurement of substitute
 * goods or services; loss of use, data, or profits; or business
 * interruption) however caused and on any theory of liability, whether
 * in contract, strict liability, or tort (including negligence or
 * otherwise) arising in any way out of the use of this software, even
 * if advised of the possibility of such damage.
 *
 */
#define _GNU_SOURCE

#include <unistd.h>
#include <poll.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <pwd.h>
#include <errno.h>
#include <limits.h>
#include <grp.h>
#include <signal.h>
#include <pthread.h>
#include <ctype.h>

#include <nc_client.h>

#include "../config.h"

#ifdef WITH_NOTIFICATIONS
#include "notification_server.h"
#endif

#include "message_type.h"
#include "netopeerguid.h"

#define SCHEMA_DIR "/tmp/yang_models"
#define MAX_PROCS 5
#define SOCKET_FILENAME "/var/run/netopeerguid.sock"
#define MAX_SOCKET_CL 10
#define BUFFER_SIZE 4096
#define ACTIVITY_CHECK_INTERVAL 10  /**< timeout in seconds, how often activity is checked */
#define ACTIVITY_TIMEOUT    (60*60)  /**< timeout in seconds, after this time, session is automaticaly closed. */

/* sleep in master process for non-blocking socket reading, in msec */
#define SLEEP_TIME 200

#ifndef offsetof
#define offsetof(type, member) ((size_t) ((type *) 0)->member)
#endif

/* timeout in msec */
struct timeval timeout = { 1, 0 };

#define NCWITHDEFAULTS  NCWD_MODE_NOTSET

#define MSG_OK 0
#define MSG_OPEN  1
#define MSG_DATA  2
#define MSG_CLOSE 3
#define MSG_ERROR 4
#define MSG_UNKNOWN 5

pthread_rwlock_t session_lock; /**< mutex protecting netconf_sessions_list from multiple access errors */
pthread_mutex_t ntf_history_lock; /**< mutex protecting notification history list */
pthread_mutex_t ntf_hist_clbc_mutex; /**< mutex protecting notification history list */
pthread_mutex_t json_lock; /**< mutex for protecting json-c calls */

unsigned int session_key_generator = 1;
struct session_with_mutex *netconf_sessions_list = NULL;
static const char *sockname;
static pthread_key_t notif_history_key;
pthread_key_t err_reply_key;
volatile int isterminated = 0;
static char* password;

json_object *create_ok_reply(void);
json_object *create_data_reply(const char *data);
static char *netconf_getschema(unsigned int session_key, const char *identifier, const char *version,
                               const char *format, json_object **err);
static void node_add_metadata_recursive(struct lyd_node *data_tree, const struct lys_module *module,
                                        json_object *data_json_parent);
static void node_metadata_typedef(struct lys_tpdf *tpdf, json_object *parent);

static void
signal_handler(int sign)
{
    switch (sign) {
    case SIGINT:
    case SIGTERM:
        isterminated = 1;
        break;
    }
}

int
netconf_callback_ssh_hostkey_check(const char* UNUSED(hostname), ssh_session UNUSED(session))
{
    /* always approve */
    return (EXIT_SUCCESS);
}

char *
netconf_callback_sshauth_passphrase(const char *UNUSED(priv_key_file))
{
    char *buf;
    buf = strdup(password);
    return (buf);
}

char *
netconf_callback_sshauth_password(const char *UNUSED(username), const char *UNUSED(hostname))
{
    char *buf;
    buf = strdup(password);
    return (buf);
}

char *
netconf_callback_sshauth_interactive(const char *UNUSED(name), const char *UNUSED(instruction),
                                     const char *UNUSED(prompt), int UNUSED(echo))
{
    char *buf;
    buf = strdup(password);
    return (buf);
}

void
netconf_callback_error_process(const char *UNUSED(tag),
        const char *UNUSED(type),
        const char *UNUSED(severity),
        const char *UNUSED(apptag),
        const char *UNUSED(path),
        const char *message,
        const char *UNUSED(attribute),
        const char *UNUSED(element),
        const char *UNUSED(ns),
        const char *UNUSED(sid))
{
    json_object **err_reply_p = (json_object **) pthread_getspecific(err_reply_key);
    if (err_reply_p == NULL) {
        ERROR("Error message was not allocated. %s", __func__);
        return;
    }
    json_object *err_reply = *err_reply_p;

    json_object *array = NULL;
    if (err_reply == NULL) {
        ERROR("error calback: empty error list");
        pthread_mutex_lock(&json_lock);
        err_reply = json_object_new_object();
        array = json_object_new_array();
        json_object_object_add(err_reply, "type", json_object_new_int(REPLY_ERROR));
        json_object_object_add(err_reply, "errors", array);
        if (message != NULL) {
            json_object_array_add(array, json_object_new_string(message));
        }
        pthread_mutex_unlock(&json_lock);
        (*err_reply_p) = err_reply;
    } else {
        ERROR("error calback: nonempty error list");
        pthread_mutex_lock(&json_lock);
        if (json_object_object_get_ex(err_reply, "errors", &array) == TRUE) {
            if (message != NULL) {
                json_object_array_add(array, json_object_new_string(message));
            }
        }
        pthread_mutex_unlock(&json_lock);
    }
    pthread_setspecific(err_reply_key, err_reply_p);
    return;
}

/**
 * should be used in locked area
 */
void
prepare_status_message(struct session_with_mutex *s, struct nc_session *session)
{
    int i;
    json_object *json_obj = NULL;
    json_object *js_tmp = NULL;
    char *old_sid = NULL;
    const char *j_old_sid = NULL;
    char str_port[6];
    const char **cpblts;
    struct lyd_node *yanglib, *module, *node;

    if (s == NULL) {
        ERROR("No session given.");
        return;
    }

    pthread_mutex_lock(&json_lock);
    if (s->hello_message != NULL) {
        ERROR("clean previous hello message");
        if (json_object_object_get_ex(s->hello_message, "sid", &js_tmp) == TRUE) {
            j_old_sid = json_object_get_string(js_tmp);
            if (j_old_sid != NULL) {
                old_sid = strdup(j_old_sid);
            }
        }
        json_object_put(s->hello_message);
        s->hello_message = NULL;
    }
    s->hello_message = json_object_new_object();
    if (session != NULL) {
        if (!old_sid) {
            /* we don't have old sid */
            asprintf(&old_sid, "%u", nc_session_get_id(session));
        }
        json_object_object_add(s->hello_message, "sid", json_object_new_string(old_sid));
        free(old_sid);
        old_sid = NULL;

        json_object_object_add(s->hello_message, "version", json_object_new_string((nc_session_get_version(session) ? "1.1":"1.0")));
        json_object_object_add(s->hello_message, "host", json_object_new_string(nc_session_get_host(session)));
        sprintf(str_port, "%u", nc_session_get_port(session));
        json_object_object_add(s->hello_message, "port", json_object_new_string(str_port));
        json_object_object_add(s->hello_message, "user", json_object_new_string(nc_session_get_username(session)));
        cpblts = nc_session_get_cpblts(session);
        if (cpblts) {
            json_obj = json_object_new_array();
            for (i = 0; cpblts[i]; ++i) {
                json_object_array_add(json_obj, json_object_new_string(cpblts[i]));
            }
            json_object_object_add(s->hello_message, "capabilities", json_obj);
        }

        yanglib = ly_ctx_info(nc_session_get_ctx(session));
        if (yanglib) {
            json_obj = json_object_new_array();
            LY_TREE_FOR(yanglib->child, module) {
                if (!strcmp(module->schema->name, "module")) {
                    LY_TREE_FOR(module->child, node) {
                        if (!strcmp(node->schema->name, "name")) {
                            json_object_array_add(json_obj, json_object_new_string(((struct lyd_node_leaf_list *)node)->value_str));
                            break;
                        }
                    }
                }
            }
            json_object_object_add(s->hello_message, "models", json_obj);

            lyd_free(node);
        }

        DEBUG("%s", json_object_to_json_string(s->hello_message));
    } else {
        ERROR("Session was not given.");
        json_object_object_add(s->hello_message, "type", json_object_new_int(REPLY_ERROR));
        json_object_object_add(s->hello_message, "error-message", json_object_new_string("Invalid session identifier."));
    }
    DEBUG("Status info from hello message prepared");
    pthread_mutex_unlock(&json_lock);
}

void
create_err_reply_p()
{
    json_object **err_reply = calloc(1, sizeof(json_object **));
    if (err_reply == NULL) {
        ERROR("Allocation of err_reply storage failed!");
        return;
    }
    if (pthread_setspecific(err_reply_key, err_reply) != 0) {
        ERROR("cannot set thread-specific value.");
    }
}

void
clean_err_reply()
{
    json_object **err_reply = (json_object **) pthread_getspecific(err_reply_key);
    if (err_reply != NULL) {
        if (*err_reply != NULL) {
            pthread_mutex_lock(&json_lock);
            json_object_put(*err_reply);
            pthread_mutex_unlock(&json_lock);
        }
        if (pthread_setspecific(err_reply_key, err_reply) != 0) {
            ERROR("Cannot set thread-specific hash value.");
        }
    }
}

void
free_err_reply()
{
    json_object **err_reply = (json_object **) pthread_getspecific(err_reply_key);
    if (err_reply != NULL) {
        if (*err_reply != NULL) {
            pthread_mutex_lock(&json_lock);
            json_object_put(*err_reply);
            pthread_mutex_unlock(&json_lock);
        }
        free(err_reply);
        err_reply = NULL;
        if (pthread_setspecific(err_reply_key, err_reply) != 0) {
            ERROR("Cannot set thread-specific hash value.");
        }
    }
}

static struct session_with_mutex *
session_get_locked(unsigned int session_key, json_object **err)
{
    struct session_with_mutex *locked_session;

    /* get non-exclusive (read) access to sessions_list (conns) */
    DEBUG("LOCK wrlock %s", __func__);
    if (pthread_rwlock_rdlock(&session_lock) != 0) {
        if (*err) {
            *err = create_error_reply("Locking failed.");
        }
        return NULL;
    }
    /* get session where send the RPC */
    for (locked_session = netconf_sessions_list;
         locked_session && (locked_session->session_key != session_key);
         locked_session = locked_session->next);
    if (!locked_session) {
        if (*err) {
            *err = create_error_reply("Session not found.");
        }
        return NULL;
    }

    /* get exclusive access to session */
    DEBUG("LOCK mutex %s", __func__);
    if (pthread_mutex_lock(&locked_session->lock) != 0) {
        if (*err) {
            *err = create_error_reply("Locking failed.");
        }
        goto wrlock_fail;
    }
    return locked_session;

wrlock_fail:
    DEBUG("UNLOCK wrlock %s", __func__);
    pthread_rwlock_unlock(&session_lock);
    return NULL;
}

static void
session_user_activity(const char *username)
{
    struct session_with_mutex *sess;

    for (sess = netconf_sessions_list; sess; sess = sess->next) {
        if (!strcmp(nc_session_get_username(sess->session), username)) {
            sess->last_activity = time(NULL);
        }
    }
}

static void
session_unlock(struct session_with_mutex *locked_session)
{
    DEBUG("UNLOCK mutex %s", __func__);
    pthread_mutex_unlock(&locked_session->lock);
    DEBUG("UNLOCK wrlock %s", __func__);
    pthread_rwlock_unlock(&session_lock);
}

static void
node_metadata_text(const char *text, const char *name, json_object *parent)
{
    json_object *obj;

    if (!text) {
        return;
    }

    obj = json_object_new_string(text);
    json_object_object_add(parent, name, obj);
}

static void
node_metadata_restr(struct lys_restr *restr, const char *name, json_object *parent)
{
    json_object *obj;

    if (!restr) {
        return;
    }

    obj = json_object_new_string(restr->expr);
    json_object_object_add(parent, name, obj);
}

static void
node_metadata_must(uint8_t must_size, struct lys_restr *must, json_object *parent)
{
    uint8_t i;
    json_object *array, *obj;

    if (!must_size || !must) {
        return;
    }

    array = json_object_new_array();

    for (i = 0; i < must_size; ++i) {
        obj = json_object_new_string(must[i].expr);
        json_object_array_add(array, obj);
    }

    json_object_object_add(parent, "must", array);
}

static void
node_metadata_basic(struct lys_node *node, json_object *parent)
{
    json_object *obj;

    /* description */
    node_metadata_text(node->dsc, "description", parent);

    /* reference */
    node_metadata_text(node->ref, "reference", parent);

    /* config */
    if (node->flags & LYS_CONFIG_R) {
        obj = json_object_new_boolean(0);
    } else {
        obj = json_object_new_boolean(1);
    }
    json_object_object_add(parent, "config", obj);

    /* status */
    if (node->flags & LYS_STATUS_DEPRC) {
        obj = json_object_new_string("deprecated");
    } else if (node->flags & LYS_STATUS_OBSLT) {
        obj = json_object_new_string("obsolete");
    } else {
        obj = json_object_new_string("current");
    }
    json_object_object_add(parent, "status", obj);

    /* mandatory */
    if (node->flags & LYS_MAND_TRUE) {
        obj = json_object_new_boolean(1);
    } else {
        obj = json_object_new_boolean(0);
    }
    json_object_object_add(parent, "mandatory", obj);

    /* NACM extensions */
    if (node->nacm) {
        if (node->nacm & LYS_NACM_DENYW) {
            obj = json_object_new_string("default-deny-write");
        } else {
            obj = json_object_new_string("default-deny-all");
        }
        json_object_object_add(parent, "ext", obj);
    }
}

static void
node_metadata_when(struct lys_when *when, json_object *parent)
{
    json_object *obj;

    if (!when) {
        return;
    }

    obj = json_object_new_string(when->cond);
    json_object_object_add(parent, "when", obj);
}

static void
node_metadata_children_recursive(struct lys_node *node, json_object **child_array, json_object **choice_array)
{
    json_object *obj;
    struct lys_node *child;

    if (!node->child) {
        return;
    }

    LY_TREE_FOR(node->child, child) {
        if (child->nodetype == LYS_USES) {
            node_metadata_children_recursive(child, child_array, choice_array);
        } else if (child->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML)) {
            obj = json_object_new_string(child->name);
            if (!*child_array) {
                *child_array = json_object_new_array();
            }
            json_object_array_add(*child_array, obj);
        } else if (child->nodetype == LYS_CHOICE) {
            obj = json_object_new_string(child->name);
            if (!*choice_array) {
                *choice_array = json_object_new_array();
            }
            json_object_array_add(*choice_array, obj);
        }
    }
}

static void
node_metadata_cases_recursive(struct lys_node_choice *choice, json_object *array)
{
    json_object *obj;
    struct lys_node *child;

    if (!choice->child) {
        return;
    }

    LY_TREE_FOR(choice->child, child) {
        if (child->nodetype == LYS_USES) {
            node_metadata_cases_recursive((struct lys_node_choice *)child, array);
        } else if (child->nodetype & (LYS_CONTAINER | LYS_LEAF | LYS_LEAFLIST | LYS_LIST | LYS_ANYXML | LYS_CASE)) {
            obj = json_object_new_string(child->name);
            json_object_array_add(array, obj);
        }
    }
}

static void
node_metadata_min_max(uint32_t min, uint32_t max, json_object *parent)
{
    json_object *obj;

    if (min) {
        obj = json_object_new_int(min);
        json_object_object_add(parent, "min-elements", obj);
    }

    if (max) {
        obj = json_object_new_int(max);
        json_object_object_add(parent, "max-elements", obj);
    }
}

static void
node_metadata_ident_recursive(struct lys_ident *ident, json_object *array)
{
    struct lys_ident_der *cur;
    json_object *obj;

    if (!ident) {
        return;
    }

    obj = json_object_new_string(ident->name);
    json_object_array_add(array, obj);

    for (cur = ident->der; cur; cur = cur->next) {
        node_metadata_ident_recursive(cur->ident, array);
    }
}

static void
node_metadata_type(struct lys_type *type, struct lys_module *module, json_object *parent)
{
    json_object *obj, *array, *item;
    char *str;
    int i;

    /* built-in YANG type */
    if (!type->der->module) {
        switch (type->base) {
        case LY_TYPE_BINARY:
            node_metadata_text("binary", "type", parent);
            node_metadata_restr(type->info.binary.length, "length", parent);
            break;
        case LY_TYPE_BITS:
            node_metadata_text("bits", "type", parent);

            array = json_object_new_array();
            for (i = 0; i < type->info.bits.count; ++i) {
                item = json_object_new_object();
                obj = json_object_new_string(type->info.bits.bit[i].name);
                json_object_object_add(item, "name", obj);
                obj = json_object_new_int(type->info.bits.bit[i].pos);
                json_object_object_add(item, "position", obj);
                json_object_array_add(array, item);
            }
            json_object_object_add(parent, "bits", array);
            break;
        case LY_TYPE_BOOL:
            node_metadata_text("bool", "type", parent);
            break;
        case LY_TYPE_DEC64:
            node_metadata_text("decimal64", "type", parent);
            node_metadata_restr(type->info.dec64.range, "range", parent);
            obj = json_object_new_int(type->info.dec64.dig);
            json_object_object_add(parent, "fraction-digits", obj);
            break;
        case LY_TYPE_EMPTY:
            node_metadata_text("empty", "type", parent);
            break;
        case LY_TYPE_ENUM:
            node_metadata_text("enumeration", "type", parent);

            array = json_object_new_array();
            for (i = 0; i < type->info.enums.count; ++i) {
                obj = json_object_new_string(type->info.enums.enm[i].name);
                json_object_array_add(array, obj);
            }
            json_object_object_add(parent, "enumval", array);
            break;
        case LY_TYPE_IDENT:
            node_metadata_text("identityref", "type", parent);

            array = json_object_new_array();
            node_metadata_ident_recursive(type->info.ident.ref, array);
            json_object_object_add(parent, "identityval", array);
            break;
        case LY_TYPE_INST:
            node_metadata_text("instance-identifier", "type", parent);
            if (type->info.inst.req == -1) {
                obj = json_object_new_boolean(0);
            } else {
                obj = json_object_new_boolean(1);
            }
            json_object_object_add(parent, "require-instance", obj);
            break;
        case LY_TYPE_LEAFREF:
            node_metadata_text("leafref", "type", parent);
            node_metadata_text(type->info.lref.path, "path", parent);
            break;
        case LY_TYPE_STRING:
            node_metadata_text("string", "type", parent);
            node_metadata_restr(type->info.str.length, "length", parent);
            if (type->info.str.pat_count) {
                array = json_object_new_array();
                for (i = 0; i < type->info.str.pat_count; ++i) {
                    obj = json_object_new_string(type->info.str.patterns[i].expr);
                    json_object_array_add(array, obj);
                }
                json_object_object_add(parent, "pattern", array);
            }
            break;
        case LY_TYPE_UNION:
            node_metadata_text("union", "type", parent);
            array = json_object_new_array();
            for (i = 0; i < type->info.uni.count; ++i) {
                obj = json_object_new_object();
                node_metadata_type(&type->info.uni.types[i], module, obj);
                json_object_array_add(array, obj);
            }
            json_object_object_add(parent, "types", array);
            break;
        case LY_TYPE_INT8:
            node_metadata_text("int8", "type", parent);
            node_metadata_restr(type->info.num.range, "range", parent);
            break;
        case LY_TYPE_UINT8:
            node_metadata_text("uint8", "type", parent);
            node_metadata_restr(type->info.num.range, "range", parent);
            break;
        case LY_TYPE_INT16:
            node_metadata_text("int16", "type", parent);
            node_metadata_restr(type->info.num.range, "range", parent);
            break;
        case LY_TYPE_UINT16:
            node_metadata_text("uint16", "type", parent);
            node_metadata_restr(type->info.num.range, "range", parent);
            break;
        case LY_TYPE_INT32:
            node_metadata_text("int32", "type", parent);
            node_metadata_restr(type->info.num.range, "range", parent);
            break;
        case LY_TYPE_UINT32:
            node_metadata_text("uint32", "type", parent);
            node_metadata_restr(type->info.num.range, "range", parent);
            break;
        case LY_TYPE_INT64:
            node_metadata_text("int64", "type", parent);
            node_metadata_restr(type->info.num.range, "range", parent);
            break;
        case LY_TYPE_UINT64:
            node_metadata_text("uint64", "type", parent);
            node_metadata_restr(type->info.num.range, "range", parent);
            break;
        default:
            ERROR("Internal: unknown type (%s:%d)", __FILE__, __LINE__);
            break;
        }

    /* typedef */
    } else {
        if (!module || !type->module_name || !strcmp(type->module_name, module->name)) {
            node_metadata_text(type->der->name, "type", parent);
        } else {
            asprintf(&str, "%s:%s", type->module_name, type->der->name);
            node_metadata_text(str, "type", parent);
            free(str);
        }
        obj = json_object_new_object();
        node_metadata_typedef(type->der, obj);
        json_object_object_add(parent, "typedef", obj);
    }
}

static void
node_metadata_typedef(struct lys_tpdf *tpdf, json_object *parent)
{
    json_object *obj;

    /* description */
    node_metadata_text(tpdf->dsc, "description", parent);

    /* reference */
    node_metadata_text(tpdf->ref, "reference", parent);

    /* status */
    if (tpdf->flags & LYS_STATUS_DEPRC) {
        obj = json_object_new_string("deprecated");
    } else if (tpdf->flags & LYS_STATUS_OBSLT) {
        obj = json_object_new_string("obsolete");
    } else {
        obj = json_object_new_string("current");
    }
    json_object_object_add(parent, "status", obj);

    /* type */
    node_metadata_type(&tpdf->type, tpdf->module, parent);

    /* units */
    node_metadata_text(tpdf->units, "units", parent);

    /* default */
    node_metadata_text(tpdf->dflt, "default", parent);
}

static void
node_metadata_container(struct lys_node_container *cont, json_object *parent)
{
    json_object *obj, *child_array = NULL, *choice_array = NULL;

    /* element type */
    obj = json_object_new_string("container");
    json_object_object_add(parent, "eltype", obj);

    /* shared info */
    node_metadata_basic((struct lys_node *)cont, parent);

    /* must */
    node_metadata_must(cont->must_size, cont->must, parent);

    /* presence */
    node_metadata_text(cont->presence, "presence", parent);

    /* when */
    node_metadata_when(cont->when, parent);

    /* children & choice */
    node_metadata_children_recursive((struct lys_node *)cont, &child_array, &choice_array);
    if (child_array) {
        json_object_object_add(parent, "children", child_array);
    }
    if (choice_array) {
        json_object_object_add(parent, "choice", choice_array);
    }
}

static void
node_metadata_choice(struct lys_node_choice *choice, json_object *parent)
{
    json_object *obj, *array;

    /* element type */
    obj = json_object_new_string("choice");
    json_object_object_add(parent, "eltype", obj);

    /* shared info */
    node_metadata_basic((struct lys_node *)choice, parent);

    /* default */
    node_metadata_text(choice->dflt->name, "default", parent);

    /* when */
    node_metadata_when(choice->when, parent);

    /* cases */
    if (choice->child) {
        array = json_object_new_array();
        node_metadata_cases_recursive(choice, array);
        json_object_object_add(parent, "cases", array);
    }
}

static void
node_metadata_leaf(struct lys_node_leaf *leaf, json_object *parent)
{
    json_object *obj;
    struct lys_node_list *list;
    int is_key, i;

    /* element type */
    obj = json_object_new_string("leaf");
    json_object_object_add(parent, "eltype", obj);

    /* shared info */
    node_metadata_basic((struct lys_node *)leaf, parent);

    /* type */
    node_metadata_type(&leaf->type, leaf->module, parent);

    /* units */
    node_metadata_text(leaf->units, "units", parent);

    /* default */
    node_metadata_text(leaf->dflt, "default", parent);

    /* must */
    node_metadata_must(leaf->must_size, leaf->must, parent);

    /* when */
    node_metadata_when(leaf->when, parent);

    /* iskey */
    is_key = 0;
    list = (struct lys_node_list *)lys_parent((struct lys_node *)leaf);
    if (list && (list->nodetype == LYS_LIST)) {
        for (i = 0; i < list->keys_size; ++i) {
            if (list->keys[i] == leaf) {
                is_key = 1;
                break;
            }
        }
    }
    obj = json_object_new_boolean(is_key);
    json_object_object_add(parent, "iskey", obj);
}

static void
node_metadata_leaflist(struct lys_node_leaflist *llist, json_object *parent)
{
    json_object *obj;

    /* element type */
    obj = json_object_new_string("leaf-list");
    json_object_object_add(parent, "eltype", obj);

    /* shared info */
    node_metadata_basic((struct lys_node *)llist, parent);

    /* type */
    node_metadata_type(&llist->type, llist->module, parent);

    /* units */
    node_metadata_text(llist->units, "units", parent);

    /* must */
    node_metadata_must(llist->must_size, llist->must, parent);

    /* when */
    node_metadata_when(llist->when, parent);

    /* min/max-elements */
    node_metadata_min_max(llist->min, llist->max, parent);
}

static void
node_metadata_list(struct lys_node_list *list, json_object *parent)
{
    json_object *obj, *array, *child_array = NULL, *choice_array = NULL;;
    int i;
    unsigned int j;

    /* element type */
    obj = json_object_new_string("list");
    json_object_object_add(parent, "eltype", obj);

    /* shared info */
    node_metadata_basic((struct lys_node *)list, parent);

    /* must */
    node_metadata_must(list->must_size, list->must, parent);

    /* when */
    node_metadata_when(list->when, parent);

    /* min/max-elements */
    node_metadata_min_max(list->min, list->max, parent);

    /* keys */
    if (list->keys_size) {
        array = json_object_new_array();
        for (i = 0; i < list->keys_size; ++i) {
            obj = json_object_new_string(list->keys[i]->name);
            json_object_array_add(array, obj);
        }
        json_object_object_add(parent, "keys", array);
    }

    /* unique */
    if (list->unique_size) {
        array = json_object_new_array();
        for (i = 0; i < list->unique_size; ++i) {
            for (j = 0; j < list->unique[i].expr_size; ++j) {
                obj = json_object_new_string(list->unique[i].expr[j]);
                json_object_array_add(array, obj);
            }
        }
        json_object_object_add(parent, "unique", array);
    }

    /* children & choice */
    node_metadata_children_recursive((struct lys_node *)list, &child_array, &choice_array);
    if (child_array) {
        json_object_object_add(parent, "children", child_array);
    }
    if (choice_array) {
        json_object_object_add(parent, "choice", choice_array);
    }
}

static void
node_metadata_anyxml(struct lys_node_anyxml *anyxml, json_object *parent)
{
    json_object *obj;

    /* element type */
    obj = json_object_new_string("anyxml");
    json_object_object_add(parent, "eltype", obj);

    /* shared info */
    node_metadata_basic((struct lys_node *)anyxml, parent);

    /* must */
    node_metadata_must(anyxml->must_size, anyxml->must, parent);

    /* when */
    node_metadata_when(anyxml->when, parent);

}

static void
node_metadata_case(struct lys_node_case *cas, json_object *parent)
{
    json_object *obj;

    /* element type */
    obj = json_object_new_string("case");
    json_object_object_add(parent, "eltype", obj);

    /* shared info */
    node_metadata_basic((struct lys_node *)cas, parent);

    /* when */
    node_metadata_when(cas->when, parent);
}

static void
node_metadata_rpc(struct lys_node_rpc *rpc, json_object *parent)
{
    json_object *obj;

    /* element type */
    obj = json_object_new_string("rpc");
    json_object_object_add(parent, "eltype", obj);

    /* description */
    node_metadata_text(rpc->dsc, "description", parent);

    /* reference */
    node_metadata_text(rpc->ref, "reference", parent);

    /* status */
    if (rpc->flags & LYS_STATUS_DEPRC) {
        obj = json_object_new_string("deprecated");
    } else if (rpc->flags & LYS_STATUS_OBSLT) {
        obj = json_object_new_string("obsolete");
    } else {
        obj = json_object_new_string("current");
    }
    json_object_object_add(parent, "status", obj);
}

static void
node_metadata_model(const struct lys_module *module, json_object *parent)
{
    json_object *obj, *array, *item;
    int i;

    /* yang-version */
    if (module->version == 2) {
        obj = json_object_new_string("1.1");
    } else {
        obj = json_object_new_string("1.0");
    }
    json_object_object_add(parent, "yang-version", obj);

    /* namespace */
    node_metadata_text(module->ns, "namespace", parent);

    /* prefix */
    node_metadata_text(module->prefix, "prefix", parent);

    /* contact */
    node_metadata_text(module->contact, "contact", parent);

    /* organization */
    node_metadata_text(module->org, "organization", parent);

    /* revision */
    if (module->rev_size) {
        node_metadata_text(module->rev[0].date, "revision", parent);
    }

    /* description */
    node_metadata_text(module->dsc, "description", parent);

    /* import */
    if (module->imp_size) {
        array = json_object_new_array();
        for (i = 0; i < module->imp_size; ++i) {
            item = json_object_new_object();

            node_metadata_text(module->imp[i].module->name, "name", item);
            node_metadata_text(module->imp[i].prefix, "prefix", item);
            if (module->imp[i].rev && module->imp[i].rev[0]) {
                node_metadata_text(module->imp[i].rev, "revision", item);
            }

            json_object_array_add(array, item);
        }
        json_object_object_add(parent, "imports", array);
    }

    /* include */
    if (module->inc_size) {
        array = json_object_new_array();
        for (i = 0; i < module->inc_size; ++i) {
            item = json_object_new_object();

            node_metadata_text(module->inc[i].submodule->name, "name", item);
            if (module->inc[i].rev && module->inc[i].rev[0]) {
                node_metadata_text(module->inc[i].rev, "revision", item);
            }

            json_object_array_add(array, item);
        }
        json_object_object_add(parent, "includes", array);
    }
}

/**
 * \defgroup netconf_operations NETCONF operations
 * The list of NETCONF operations that mod_netconf supports.
 * @{
 */

/**
 * \brief Send RPC and wait for reply with timeout.
 *
 * \param[in] session libnetconf session
 * \param[in] rpc     prepared RPC message
 * \param[in] timeout timeout in miliseconds, -1 for blocking, 0 for non-blocking
 * \param[out] reply  reply from the server
 * \return NC_MSG_WOULDBLOCK or NC_MSG_ERROR.
 * On success, it returns NC_MSG_REPLY.
 */
NC_MSG_TYPE
netconf_send_recv_timed(struct nc_session *session, struct nc_rpc *rpc, int timeout, int strict, struct nc_reply **reply)
{
    uint64_t msgid;
    NC_MSG_TYPE ret;
    ret = nc_send_rpc(session, rpc, timeout, &msgid);
    if (ret != NC_MSG_RPC) {
        return ret;
    }

    while ((ret = nc_recv_reply(session, rpc, msgid, timeout, (strict ? LYD_OPT_STRICT : 0), reply)) == NC_MSG_NOTIF);

    return ret;
}

/**
 * \brief Connect to NETCONF server
 *
 * \warning Session_key hash is not bound with caller identification. This could be potential security risk.
 */
static unsigned int
netconf_connect(const char *host, const char *port, const char *user, const char *pass, const char *privkey)
{
    struct nc_session* session = NULL;
    struct session_with_mutex *locked_session, *last_session;
    char *pubkey;

    /* connect to the requested NETCONF server */
    password = (char*)pass;
    if (privkey) {
        nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 3);
        asprintf(&pubkey, "%s.pub", privkey);
        nc_client_ssh_add_keypair(pubkey, privkey);
        free(pubkey);
    }
    nc_client_ssh_set_username(user);
    DEBUG("prepare to connect %s@%s:%s", user, host, port);
    session = nc_connect_ssh(host, (unsigned short)atoi(port), NULL);
    DEBUG("nc_session_connect done");

    /* if connected successful, add session to the list */
    if (session != NULL) {
        if ((locked_session = calloc(1, sizeof(struct session_with_mutex))) == NULL || pthread_mutex_init (&locked_session->lock, NULL) != 0) {
            nc_session_free(session, NULL);
            session = NULL;
            free(locked_session);
            locked_session = NULL;
            ERROR("Creating structure session_with_mutex failed %d (%s)", errno, strerror(errno));
            return 0;
        }
        locked_session->session = session;
        locked_session->hello_message = NULL;
        locked_session->closed = 0;
        pthread_mutex_init(&locked_session->lock, NULL);
        DEBUG("Before session_lock");
        /* get exclusive access to sessions_list (conns) */
        DEBUG("LOCK wrlock %s", __func__);
        if (pthread_rwlock_wrlock(&session_lock) != 0) {
            nc_session_free(session, NULL);
            free(locked_session);
            ERROR("Error while locking rwlock: %d (%s)", errno, strerror(errno));
            return 0;
        }
        locked_session->ntfc_subscribed = 0;
        DEBUG("Add connection to the list");
        if (!netconf_sessions_list) {
            netconf_sessions_list = locked_session;
        } else {
            for (last_session = netconf_sessions_list; last_session->next; last_session = last_session->next);
            last_session->next = locked_session;
            locked_session->prev = last_session;
        }
        session_user_activity(nc_session_get_username(locked_session->session));

        /* no need to lock session, noone can read it while we have wrlock */

        /* store information about session from hello message for future usage */
        prepare_status_message(locked_session, session);

        DEBUG("NETCONF session established");
        locked_session->session_key = session_key_generator;
        ++session_key_generator;
        if (session_key_generator == UINT_MAX) {
            session_key_generator = 1;
        }

        DEBUG("Before session_unlock");
        /* unlock session list */
        DEBUG("UNLOCK wrlock %s", __func__);
        if (pthread_rwlock_unlock(&session_lock) != 0) {
            ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
        }

        return locked_session->session_key;
    }

    ERROR("Connection could not be established");
    return 0;
}

static int
close_and_free_session(struct session_with_mutex *locked_session)
{
    int i;

    DEBUG("lock private lock.");
    DEBUG("LOCK mutex %s", __func__);
    if (pthread_mutex_lock(&locked_session->lock) != 0) {
        ERROR("Error while locking rwlock");
    }
    locked_session->ntfc_subscribed = 0;
    locked_session->closed = 1;
    if (locked_session->session != NULL) {
        nc_session_free(locked_session->session, NULL);
        locked_session->session = NULL;
    }
    DEBUG("session closed.");
    DEBUG("unlock private lock.");
    DEBUG("UNLOCK mutex %s", __func__);
    if (pthread_mutex_unlock(&locked_session->lock) != 0) {
        ERROR("Error while locking rwlock");
    }

    DEBUG("unlock session lock.");
    DEBUG("closed session, disabled notif(?), wait 0.5s");
    usleep(500000); /* let notification thread stop */

    /* session shouldn't be used by now */
    for (i = 0; i < locked_session->notif_count; ++i) {
        free(locked_session->notifications[i].content);
    }
    free(locked_session->notifications);
    pthread_mutex_destroy(&locked_session->lock);
    if (locked_session->hello_message != NULL) {
        json_object_put(locked_session->hello_message);
        locked_session->hello_message = NULL;
    }
    locked_session->session = NULL;
    free(locked_session);
    locked_session = NULL;
    DEBUG("NETCONF session closed, everything cleared.");
    return (EXIT_SUCCESS);
}

static int
netconf_close(unsigned int session_key, json_object **reply)
{
    struct session_with_mutex *locked_session;

    DEBUG("Session to close: %u", session_key);

    /* get exclusive (write) access to sessions_list (conns) */
    DEBUG("lock session lock.");
    DEBUG("LOCK wrlock %s", __func__);
    if (pthread_rwlock_wrlock (&session_lock) != 0) {
        ERROR("Error while locking rwlock");
        (*reply) = create_error_reply("Internal: Error while locking.");
        return EXIT_FAILURE;
    }
    /* remove session from the active sessions list -> nobody new can now work with session */
    for (locked_session = netconf_sessions_list;
         locked_session && (locked_session->session_key != session_key);
         locked_session = locked_session->next);

    if (!locked_session) {
        ERROR("Could not find the session %u to close.", session_key);
        (*reply) = create_error_reply("Internal: Error while finding a session.");
        return EXIT_FAILURE;
    }

    if (!locked_session->prev) {
        netconf_sessions_list = netconf_sessions_list->next;
        if (netconf_sessions_list) {
            netconf_sessions_list->prev = NULL;
        }
    } else {
        locked_session->prev->next = locked_session->next;
        if (locked_session->next) {
            locked_session->next->prev = locked_session->prev;
        }
    }

    DEBUG("UNLOCK wrlock %s", __func__);
    if (pthread_rwlock_unlock (&session_lock) != 0) {
        ERROR("Error while unlocking rwlock");
        (*reply) = create_error_reply("Internal: Error while unlocking.");
    }

    if ((locked_session != NULL) && (locked_session->session != NULL)) {
        return close_and_free_session(locked_session);
    } else {
        ERROR("Unknown session to close");
        (*reply) = create_error_reply("Internal: Unkown session to close.");
        return (EXIT_FAILURE);
    }
    (*reply) = NULL;
}

/**
 * Test reply message type and return error message.
 *
 * \param[in] session   nc_session internal struct
 * \param[in] session_key session ID, 0 to disable disconnect on error
 * \param[in] msgt  RPC-REPLY message type
 * \param[out] data
 * \return NULL on success
 */
json_object *
netconf_test_reply(struct nc_session *session, unsigned int session_key, NC_MSG_TYPE msgt, struct nc_reply *reply, struct lyd_node **data)
{
    json_object *err = NULL;

    /* process the result of the operation */
    switch (msgt) {
        case NC_MSG_ERROR:
            if (nc_session_get_status(session) != NC_STATUS_RUNNING) {
                ERROR("mod_netconf: receiving rpc-reply failed");
                if (session_key) {
                    netconf_close(session_key, &err);
                }
                if (err != NULL) {
                    return err;
                }
                return create_error_reply("Internal: Receiving RPC-REPLY failed.");
            }
        case NC_MSG_NONE:
            /* there is error handled by callback */
            if (data != NULL) {
                free(*data);
                (*data) = NULL;
            }
            return NULL;
        case NC_MSG_REPLY:
            switch (reply->type) {
                case NC_RPL_OK:
                    if ((data != NULL) && (*data != NULL)) {
                        free(*data);
                        (*data) = NULL;
                    }
                    return create_ok_reply();
                case NC_RPL_DATA:
                    if (((*data) = ((struct nc_reply_data *)reply)->data) == NULL) {
                        ERROR("mod_netconf: no data from reply");
                        return create_error_reply("Internal: No data from reply received.");
                    } else {
                        ((struct nc_reply_data *)reply)->data = NULL;
                        return NULL;
                    }
                    break;
                case NC_RPL_ERROR:
                    ERROR("mod_netconf: unexpected rpc-reply (%d)", reply->type);
                    if (data != NULL) {
                        free(*data);
                        (*data) = NULL;
                    }
                    return create_error_reply(((struct nc_reply_error *)reply)->err[0].message);
                default:
                    ERROR("mod_netconf: unexpected rpc-reply (%d)", reply->type);
                    if (data != NULL) {
                        free(*data);
                        (*data) = NULL;
                    }
                    return create_error_reply("Unknown type of NETCONF reply.");
            }
            break;
        default:
            ERROR("mod_netconf: unexpected reply message received (%d)", msgt);
            if (data != NULL) {
                free(*data);
                (*data) = NULL;
            }
            return create_error_reply("Internal: Unexpected RPC-REPLY message type.");
    }
}

json_object *
netconf_unlocked_op(struct nc_session *session, struct nc_rpc *rpc)
{
    struct nc_reply* reply = NULL;
    NC_MSG_TYPE msgt;

    /* check requests */
    if (rpc == NULL) {
        ERROR("mod_netconf: rpc is not created");
        return create_error_reply("Internal error: RPC is not created");
    }

    if (session != NULL) {
        /* send the request and get the reply */
        msgt = netconf_send_recv_timed(session, rpc, 50000, 0, &reply);
        /* process the result of the operation */
        return netconf_test_reply(session, 0, msgt, reply, NULL);
    } else {
        ERROR("Unknown session to process.");
        return create_error_reply("Internal error: Unknown session to process.");
    }
}

/**
 * Perform RPC method that returns data.
 *
 * \param[in] session_id    session identifier
 * \param[in] rpc   RPC message to perform
 * \param[out] received_data    received data string, can be NULL when no data expected, value can be set to NULL if no data received
 * \return NULL on success, json object with error otherwise
 */
static json_object *
netconf_op(unsigned int session_key, struct nc_rpc *rpc, int strict, struct lyd_node **received_data)
{
    struct session_with_mutex * locked_session;
    struct nc_reply* reply = NULL;
    json_object *res = NULL;
    struct lyd_node *data = NULL;
    NC_MSG_TYPE msgt;

    /* check requests */
    if (rpc == NULL) {
        ERROR("mod_netconf: rpc is not created");
        res = create_error_reply("Internal: RPC could not be created.");
        data = NULL;
        goto finished;
    }

    locked_session = session_get_locked(session_key, &res);
    if (!locked_session) {
        ERROR("Unknown session or locking failed.");
        goto finished;
    }

    session_user_activity(nc_session_get_username(locked_session->session));

    /* send the request and get the reply */
    msgt = netconf_send_recv_timed(locked_session->session, rpc, 2000000, strict, &reply);

    session_unlock(locked_session);

    res = netconf_test_reply(locked_session->session, session_key, msgt, reply, &data);

finished:
    nc_reply_free(reply);
    if (received_data != NULL) {
        (*received_data) = data;
    } else {
        if (data != NULL) {
            free(data);
            data = NULL;
        }
    }
    return res;
}

static char *
netconf_getconfig(unsigned int session_key, NC_DATASTORE source, const char *filter, int strict, json_object **err)
{
    struct nc_rpc* rpc;
    struct session_with_mutex *locked_session;
    json_object *res = NULL, *data_cjson;
    enum json_tokener_error tok_err;
    char *data_json;
    struct lyd_node *data, *sibling, *next;

    /* tell server to show all elements even if they have default values */
#ifdef HAVE_WITHDEFAULTS_TAGGED
    rpc = nc_rpc_getconfig(source, filter, NC_WD_MODE_ALL_TAG, NC_PARAMTYPE_CONST);
#else
    rpc = nc_rpc_getconfig(source, filter, 0, NC_PARAMTYPE_CONST);
#endif
    if (rpc == NULL) {
        ERROR("mod_netconf: creating rpc request failed");
        return (NULL);
    }

    res = netconf_op(session_key, rpc, strict, &data);
    nc_rpc_free(rpc);
    if (res != NULL) {
        (*err) = res;
    } else {
        (*err) = NULL;
    }

    if (data) {
        for (locked_session = netconf_sessions_list;
             locked_session && (locked_session->session_key != session_key);
             locked_session = locked_session->next);
        /* won't fail */

        /* print data into JSON */
        if (lyd_print_mem(&data_json, data, LYD_JSON, LYP_WITHSIBLINGS)) {
            ERROR("Printing JSON <get-config> data failed.");
            lyd_free_withsiblings(data);
            return NULL;
        }

        /* parse JSON data into cjson */
        pthread_mutex_lock(&json_lock);
        data_cjson = json_tokener_parse_verbose(data_json, &tok_err);
        if (!data_cjson) {
            ERROR("Parsing JSON config failed (%s).", json_tokener_error_desc(tok_err));
            pthread_mutex_unlock(&json_lock);
            lyd_free_withsiblings(data);
            free(data_json);
            return NULL;
        }
        free(data_json);

        /* go simultaneously through both trees and add metadata */
        LY_TREE_FOR_SAFE(data, next, sibling) {
            node_add_metadata_recursive(sibling, NULL, data_cjson);
            lyd_free(sibling);
        }

        data_json = strdup(json_object_to_json_string_ext(data_cjson, 0));
        json_object_put(data_cjson);
        pthread_mutex_unlock(&json_lock);
    }

    return (data_json);
}

static char *
netconf_getschema(unsigned int session_key, const char *identifier, const char *version, const char *format, json_object **err)
{
    struct nc_rpc *rpc;
    struct lyd_node *data = NULL;
    json_object *res = NULL;
    char *model_data = NULL, *anyxml, *ptr, *ptr2;

    /* create requests */
    rpc = nc_rpc_getschema(identifier, version, format, NC_PARAMTYPE_CONST);
    if (rpc == NULL) {
        ERROR("mod_netconf: creating rpc request failed");
        return (NULL);
    }

    res = netconf_op(session_key, rpc, 0, &data);
    nc_rpc_free(rpc);
    if (res != NULL) {
        (*err) = res;
    } else {
        (*err) = NULL;

        if (data) {
            lyxml_print_mem(&anyxml, ((struct lyd_node_anyxml *)data)->value, 0);

            /* it's with the data root node, remove it */
            if (anyxml) {
                ptr = strchr(anyxml, '>');
                ++ptr;

                ptr2 = strrchr(anyxml, '<');

                model_data = strndup(ptr, strlen(ptr) - strlen(ptr2));
                free(anyxml);
            }
        }
    }

    return (model_data);
}

static char *
netconf_get(unsigned int session_key, const char* filter, int strict, json_object **err)
{
    struct nc_rpc* rpc;
    char* data_json = NULL;
    json_object *res = NULL, *data_cjson;
    enum json_tokener_error tok_err;
    struct session_with_mutex *locked_session;
    struct lyd_node *data, *sibling, *next;

    /* create requests */
    rpc = nc_rpc_get(filter, 0, NC_PARAMTYPE_CONST);
    if (rpc == NULL) {
        ERROR("mod_netconf: creating rpc request failed");
        return (NULL);
    }

    res = netconf_op(session_key, rpc, strict, &data);
    nc_rpc_free(rpc);
    if (res != NULL) {
        (*err) = res;
    } else {
        (*err) = NULL;
    }

    if (data) {
        for (locked_session = netconf_sessions_list;
             locked_session && (locked_session->session_key != session_key);
             locked_session = locked_session->next);
        /* won't fail */

        /* print JSON data */
        if (lyd_print_mem(&data_json, data, LYD_JSON, LYP_WITHSIBLINGS)) {
            ERROR("Printing JSON <get> data failed.");
            lyd_free_withsiblings(data);
            return NULL;
        }

        /* parse JSON data into cjson */
        pthread_mutex_lock(&json_lock);
        data_cjson = json_tokener_parse_verbose(data_json, &tok_err);
        if (!data_cjson) {
            ERROR("Parsing JSON config failed (%s).", json_tokener_error_desc(tok_err));
            pthread_mutex_unlock(&json_lock);
            lyd_free_withsiblings(data);
            free(data_json);
            return NULL;
        }
        free(data_json);

        /* go simultaneously through both trees and add metadata */
        LY_TREE_FOR_SAFE(data, next, sibling) {
            node_add_metadata_recursive(sibling, NULL, data_cjson);
            lyd_free(sibling);
        }

        data_json = strdup(json_object_to_json_string_ext(data_cjson, 0));
        json_object_put(data_cjson);
        pthread_mutex_unlock(&json_lock);
    }

    return data_json;
}

static json_object *
netconf_copyconfig(unsigned int session_key, NC_DATASTORE source, NC_DATASTORE target, const char *config,
                   const char *uri_src, const char *uri_trg)
{
    struct nc_rpc* rpc;
    json_object *res = NULL;

    /* create requests */
    rpc = nc_rpc_copy(target, uri_trg, source, (config ? config : uri_src), 0, NC_PARAMTYPE_CONST);
    if (rpc == NULL) {
        ERROR("mod_netconf: creating rpc request failed");
        return create_error_reply("Internal: Creating rpc request failed");
    }

    res = netconf_op(session_key, rpc, 0, NULL);
    nc_rpc_free(rpc);

    return res;
}

static json_object *
netconf_editconfig(unsigned int session_key, NC_DATASTORE target, NC_RPC_EDIT_DFLTOP defop,
                   NC_RPC_EDIT_ERROPT erropt, NC_RPC_EDIT_TESTOPT testopt, const char *config_or_url)
{
    struct nc_rpc* rpc;
    json_object *res = NULL;

    /* create requests */
    rpc = nc_rpc_edit(target, defop, testopt, erropt, config_or_url, NC_PARAMTYPE_CONST);
    if (rpc == NULL) {
        ERROR("mod_netconf: creating rpc request failed");
        return create_error_reply("Internal: Creating rpc request failed");
    }

    res = netconf_op(session_key, rpc, 0, NULL);
    nc_rpc_free (rpc);

    return res;
}

static json_object *
netconf_killsession(unsigned int session_key, const char *sid)
{
    struct nc_rpc *rpc;
    json_object *res = NULL;

    /* create requests */
    rpc = nc_rpc_kill(atoi(sid));
    if (rpc == NULL) {
        ERROR("mod_netconf: creating rpc request failed");
        return create_error_reply("Internal: Creating rpc request failed");
    }

    res = netconf_op(session_key, rpc, 0, NULL);
    nc_rpc_free(rpc);
    return res;
}

static json_object *
netconf_onlytargetop(unsigned int session_key, NC_DATASTORE target, struct nc_rpc *(*op_func)(NC_DATASTORE))
{
    struct nc_rpc* rpc;
    json_object *res = NULL;

    /* create requests */
    rpc = op_func(target);
    if (rpc == NULL) {
        ERROR("mod_netconf: creating rpc request failed");
        return create_error_reply("Internal: Creating rpc request failed");
    }

    res = netconf_op(session_key, rpc, 0, NULL);
    nc_rpc_free (rpc);
    return res;
}

static json_object *
netconf_deleteconfig(unsigned int session_key, NC_DATASTORE target, const char *url)
{
    struct nc_rpc *rpc = NULL;
    json_object *res = NULL;
    rpc = nc_rpc_delete(target, url, NC_PARAMTYPE_CONST);
    if (rpc == NULL) {
        ERROR("mod_netconf: creating rpc request failed");
        return create_error_reply("Internal: Creating rpc request failed");
    }

    res = netconf_op(session_key, rpc, 0, NULL);
    nc_rpc_free (rpc);
    return res;
}

static json_object *
netconf_lock(unsigned int session_key, NC_DATASTORE target)
{
    return (netconf_onlytargetop(session_key, target, nc_rpc_lock));
}

static json_object *
netconf_unlock(unsigned int session_key, NC_DATASTORE target)
{
    return (netconf_onlytargetop(session_key, target, nc_rpc_unlock));
}

static json_object *
netconf_generic(unsigned int session_key, const char *xml_content, struct lyd_node **data)
{
    struct nc_rpc* rpc = NULL;
    json_object *res = NULL;

    /* create requests */
    rpc = nc_rpc_generic_xml(xml_content, NC_PARAMTYPE_CONST);
    if (rpc == NULL) {
        ERROR("mod_netconf: creating rpc request failed");
        return create_error_reply("Internal: Creating rpc request failed");
    }

    /* get session where send the RPC */
    res = netconf_op(session_key, rpc, 0, data);
    nc_rpc_free(rpc);
    return res;
}

static int
node_add_metadata(const struct lys_node *node, const struct lys_module *module, json_object *parent)
{
    struct lys_module *cur_module;
    json_object *meta_obj;
    char *obj_name;

    if (node->nodetype == LYS_INPUT) {
        /* silently skipped */
        return 0;
    }

    cur_module = node->module;
    if (cur_module->type) {
        cur_module = ((struct lys_submodule *)cur_module)->belongsto;
    }
    if (cur_module == module) {
        asprintf(&obj_name, "$@%s", node->name);
    } else {
        asprintf(&obj_name, "$@%s:%s", cur_module->name, node->name);
    }

    /* in (leaf-)lists the metadata could have already been added */
    if ((node->nodetype & (LYS_LEAFLIST | LYS_LIST)) && (json_object_object_get_ex(parent, obj_name, NULL) == TRUE)) {
        free(obj_name);
        return 1;
    }

    meta_obj = json_object_new_object();

    switch (node->nodetype) {
        case LYS_CONTAINER:
            node_metadata_container((struct lys_node_container *)node, meta_obj);
            break;
        case LYS_CHOICE:
            node_metadata_choice((struct lys_node_choice *)node, meta_obj);
            break;
        case LYS_LEAF:
            node_metadata_leaf((struct lys_node_leaf *)node, meta_obj);
            break;
        case LYS_LEAFLIST:
            node_metadata_leaflist((struct lys_node_leaflist *)node, meta_obj);
            break;
        case LYS_LIST:
            node_metadata_list((struct lys_node_list *)node, meta_obj);
            break;
        case LYS_ANYXML:
            node_metadata_anyxml((struct lys_node_anyxml *)node, meta_obj);
            break;
        case LYS_CASE:
            node_metadata_case((struct lys_node_case *)node, meta_obj);
            break;
        case LYS_RPC:
            node_metadata_rpc((struct lys_node_rpc *)node, meta_obj);
            break;
        default: /* LYS_OUTPUT */
            ERROR("Internal: unuxpected nodetype (%s:%d)", __FILE__, __LINE__);
            break;
    }

    /* just a precaution */
    if (json_object_get_type(parent) != json_type_object) {
        ERROR("Internal: wrong JSON type (%s:%d)", __FILE__, __LINE__);
        free(obj_name);
        return 1;
    }

    json_object_object_add(parent, obj_name, meta_obj);
    free(obj_name);
    return 0;
}

static void
node_add_metadata_recursive(struct lyd_node *data_tree, const struct lys_module *module, json_object *data_json_parent)
{
    struct lys_module *cur_module;
    struct lys_node *list_schema;
    struct lyd_node *child, *list_item;
    json_object *child_json, *list_child_json;
    char *child_name;
    int list_idx;

    if (data_tree->schema->nodetype & (LYS_OUTPUT | LYS_GROUPING)) {
        return;
    }

    /* add data_tree metadata */
    if (node_add_metadata(data_tree->schema, module, data_json_parent)) {
        return;
    }

    /* get data_tree module */
    cur_module = data_tree->schema->module;
    if (cur_module->type) {
        cur_module = ((struct lys_submodule *)cur_module)->belongsto;
    }

    if (!(data_tree->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYXML))) {
        /* print correct data_tree JSON name */
        if (cur_module == module) {
            asprintf(&child_name, "%s", data_tree->schema->name);
        } else {
            asprintf(&child_name, "%s:%s", cur_module->name, data_tree->schema->name);
        }

        /* go down in JSON object */
        if (json_object_object_get_ex(data_json_parent, child_name, &child_json) == FALSE) {
            ERROR("Internal: failed to get JSON object \"%s\".", child_name);
            free(child_name);
            return;
        }
        free(child_name);

        if (data_tree->schema->nodetype == LYS_LIST) {
            if (json_object_get_type(child_json) != json_type_array) {
                ERROR("Internal: type mismatch (%s:%d)", __FILE__, __LINE__);
                return;
            }
            /* go down in data tree for every item, we process them all now, skip later
             * (metadata duplicate will be detected at the beginning of this function) */
            list_idx = 0;
            list_schema = data_tree->schema;

            LY_TREE_FOR(data_tree, list_item) {
                /* another list member */
                if (list_item->schema == list_schema) {
                    list_child_json = json_object_array_get_idx(child_json, list_idx);
                    if (!list_child_json) {
                        ERROR("Internal: list \"%s\" idx out-of-bounds", list_schema->name);
                        return;
                    }
                    LY_TREE_FOR(list_item->child, child) {
                        node_add_metadata_recursive(child, cur_module, list_child_json);
                    }

                    ++list_idx;
                }
            }
        } else {
            if (json_object_get_type(child_json) != json_type_object) {
                ERROR("Internal: type mismatch (%s:%d)", __FILE__, __LINE__);
                return;
            }
            /* go down in data tree */
            LY_TREE_FOR(data_tree->child, child) {
                node_add_metadata_recursive(child, cur_module, child_json);
            }
        }
    }
}

static void
node_add_model_metadata(const struct lys_module *module, json_object *parent)
{
    json_object *obj;
    char *str;

    obj = json_object_new_object();
    node_metadata_model(module, obj);
    asprintf(&str, "$@@%s", module->name);
    json_object_object_add(parent, str, obj);
    free(str);
}

static void
node_add_children_with_metadata_recursive(const struct lys_node *node, const struct lys_module *module, json_object *parent)
{
    const struct lys_module *cur_module;
    struct lys_node *child;
    json_object *node_json;
    char *json_name;

    if (node->nodetype & (LYS_OUTPUT | LYS_GROUPING)) {
        return;
    }

    if (node->nodetype & LYS_USES) {
        cur_module = module;
        node_json = parent;
        goto children;
    }

    /* add node metadata */
    if (node_add_metadata(node, module, parent)) {
        ERROR("Internal: metadata duplicate for \"%s\".", node->name);
        return;
    }

    /* no other metadata */
    if (!node->child) {
        return;
    }

    /* get node module */
    cur_module = node->module;
    if (cur_module->type) {
        cur_module = ((struct lys_submodule *)cur_module)->belongsto;
    }

    /* create JSON object for child metadata */
    node_json = json_object_new_object();
    if (cur_module == module) {
        json_object_object_add(parent, node->name, node_json);
    } else {
        asprintf(&json_name, "%s:%s", cur_module->name, node->name);
        json_object_object_add(parent, json_name, node_json);
        free(json_name);
    }

children:
    LY_TREE_FOR(node->child, child) {
        node_add_children_with_metadata_recursive(child, cur_module, node_json);
    }
}

static json_object *
libyang_query(unsigned int session_key, const char *filter, int load_children)
{
    const struct lys_node *node;
    const struct lys_module *module = NULL;
    struct session_with_mutex *locked_session;
    json_object *ret = NULL, *data;

    locked_session = session_get_locked(session_key, &ret);
    if (!locked_session) {
        ERROR("Locking failed or session not found.");
        goto finish;
    }

    session_user_activity(nc_session_get_username(locked_session->session));

    if (filter[0] == '/') {
        node = ly_ctx_get_node(nc_session_get_ctx(locked_session->session), filter);
        if (!node) {
            ret = create_error_reply("Failed to resolve XPath filter node.");
            goto finish;
        }
    } else {
        module = ly_ctx_get_module(nc_session_get_ctx(locked_session->session), filter, NULL);
        if (!module) {
            ret = create_error_reply("Failed to find model.");
            goto finish;
        }
    }

    pthread_mutex_lock(&json_lock);
    data = json_object_new_object();

    if (module) {
        node_add_model_metadata(module, data);
        if (load_children) {
            LY_TREE_FOR(module->data, node) {
                node_add_children_with_metadata_recursive(node, NULL, data);
            }
        }
    } else {
        if (load_children) {
            node_add_children_with_metadata_recursive(node, NULL, data);
        } else {
            node_add_metadata(node, NULL, data);
        }
    }

    pthread_mutex_unlock(&json_lock);
    ret = create_data_reply(json_object_to_json_string(data));
    json_object_put(data);

finish:
    session_unlock(locked_session);
    return ret;
}

static json_object *
libyang_merge(unsigned int session_key, const char *config)
{
    struct lyd_node *data_tree = NULL, *sibling;
    struct session_with_mutex *locked_session;
    json_object *ret = NULL, *data_json = NULL;
    enum json_tokener_error err = 0;

    locked_session = session_get_locked(session_key, &ret);
    if (!locked_session) {
        ERROR("Locking failed or session not found.");
        goto finish;
    }

    session_user_activity(nc_session_get_username(locked_session->session));

    data_tree = lyd_parse_mem(nc_session_get_ctx(locked_session->session), config, LYD_JSON, LYD_OPT_STRICT);
    if (!data_tree) {
        ERROR("Creating data tree failed.");
        ret = create_error_reply("Failed to create data tree from JSON config.");
        session_unlock(locked_session);
        goto finish;
    }

    session_unlock(locked_session);

    pthread_mutex_lock(&json_lock);
    data_json = json_tokener_parse_verbose(config, &err);
    if (!data_json) {
        ERROR("Parsing JSON config failed (%s).", json_tokener_error_desc(err));
        pthread_mutex_unlock(&json_lock);
        ret = create_error_reply(json_tokener_error_desc(err));
        goto finish;
    }

    /* go simultaneously through both trees and add metadata */
    LY_TREE_FOR(data_tree, sibling) {
        node_add_metadata_recursive(sibling, NULL, data_json);
    }
    pthread_mutex_unlock(&json_lock);
    ret = create_data_reply(json_object_to_json_string(data_json));

finish:
    LY_TREE_FOR(data_tree, sibling) {
        lyd_free(sibling);
    }
    json_object_put(data_json);
    return ret;
}

/**
 * @}
 *//* netconf_operations */

void
clb_print(NC_VERB_LEVEL level, const char *msg)
{
#define FOREACH(I) \
        I(NC_VERB_ERROR) I(NC_VERB_WARNING)

#define CASE(VAL) case VAL: ERROR("%s: %s", #VAL, msg); \
    break;

    switch (level) {
    FOREACH(CASE);
    case NC_VERB_VERBOSE:
    case NC_VERB_DEBUG:
        DEBUG("DEBUG: %s", msg);
        break;
    }
    if (level == NC_VERB_ERROR) {
        /* return global error */
        netconf_callback_error_process(NULL /* tag */, NULL /* type */,
                NULL /* severity */, NULL /* apptag */,
                NULL /* path */, msg, NULL /* attribute */,
                NULL /* element */, NULL /* ns */, NULL /* sid */);
    }
}

/**
 * Receive message from client over UNIX socket and return pointer to it.
 * Caller should free message memory.
 * \param[in] client    socket descriptor of client
 * \return pointer to message
 */
char *
get_framed_message(int client)
{
    /* read json in chunked framing */
    unsigned int buffer_size = 0;
    ssize_t buffer_len = 0;
    char *buffer = NULL;
    char c;
    ssize_t ret;
    int i, chunk_len;
    char chunk_len_str[12];

    while (1) {
        /* read chunk length */
        if ((ret = recv (client, &c, 1, 0)) != 1 || c != '\n') {
            if (buffer != NULL) {
                free (buffer);
                buffer = NULL;
            }
            break;
        }
        if ((ret = recv (client, &c, 1, 0)) != 1 || c != '#') {
            if (buffer != NULL) {
                free (buffer);
                buffer = NULL;
            }
            break;
        }
        i=0;
        memset (chunk_len_str, 0, 12);
        while ((ret = recv (client, &c, 1, 0) == 1 && (isdigit(c) || c == '#'))) {
            if (i==0 && c == '#') {
                if (recv (client, &c, 1, 0) != 1 || c != '\n') {
                    /* end but invalid */
                    if (buffer != NULL) {
                        free (buffer);
                        buffer = NULL;
                    }
                }
                /* end of message, double-loop break */
                goto msg_complete;
            }
            chunk_len_str[i++] = c;
            if (i==11) {
                ERROR("Message is too long, buffer for length is not big enought!!!!");
                break;
            }
        }
        if (c != '\n') {
            if (buffer != NULL) {
                free (buffer);
                buffer = NULL;
            }
            break;
        }
        chunk_len_str[i] = 0;
        if ((chunk_len = atoi (chunk_len_str)) == 0) {
            if (buffer != NULL) {
                free (buffer);
                buffer = NULL;
            }
            break;
        }
        buffer_size += chunk_len+1;
        buffer = realloc (buffer, sizeof(char)*buffer_size);
        memset(buffer + (buffer_size-chunk_len-1), 0, chunk_len+1);
        if ((ret = recv (client, buffer+buffer_len, chunk_len, 0)) == -1 || ret != chunk_len) {
            if (buffer != NULL) {
                free (buffer);
                buffer = NULL;
            }
            break;
        }
        buffer_len += ret;
    }
msg_complete:
    return buffer;
}

NC_DATASTORE
parse_datastore(const char *ds)
{
    if (strcmp(ds, "running") == 0) {
        return NC_DATASTORE_RUNNING;
    } else if (strcmp(ds, "startup") == 0) {
        return NC_DATASTORE_STARTUP;
    } else if (strcmp(ds, "candidate") == 0) {
        return NC_DATASTORE_CANDIDATE;
    } else if (strcmp(ds, "url") == 0) {
        return NC_DATASTORE_URL;
    } else if (strcmp(ds, "config") == 0) {
        return NC_DATASTORE_CONFIG;
    }
    return -1;
}

NC_RPC_EDIT_TESTOPT
parse_testopt(const char *t)
{
    if (strcmp(t, "notset") == 0) {
        return NC_RPC_EDIT_TESTOPT_UNKNOWN;
    } else if (strcmp(t, "testset") == 0) {
        return NC_RPC_EDIT_TESTOPT_TESTSET;
    } else if (strcmp(t, "set") == 0) {
        return NC_RPC_EDIT_TESTOPT_SET;
    } else if (strcmp(t, "test") == 0) {
        return NC_RPC_EDIT_TESTOPT_TEST;
    }
    return NC_RPC_EDIT_TESTOPT_UNKNOWN;
}

json_object *
create_error_reply(const char *errmess)
{
    json_object *reply, *array;

    pthread_mutex_lock(&json_lock);
    reply = json_object_new_object();
    array = json_object_new_array();
    json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
    json_object_array_add(array, json_object_new_string(errmess));
    json_object_object_add(reply, "errors", array);
    pthread_mutex_unlock(&json_lock);

    return reply;
}

json_object *
create_data_reply(const char *data)
{
    pthread_mutex_lock(&json_lock);
    json_object *reply = json_object_new_object();
    json_object_object_add(reply, "type", json_object_new_int(REPLY_DATA));
    json_object_object_add(reply, "data", json_object_new_string(data));
    pthread_mutex_unlock(&json_lock);
    return reply;
}

json_object *
create_ok_reply(void)
{
    pthread_mutex_lock(&json_lock);
    json_object *reply = json_object_new_object();
    reply = json_object_new_object();
    json_object_object_add(reply, "type", json_object_new_int(REPLY_OK));
    pthread_mutex_unlock(&json_lock);
    return reply;
}

json_object *
create_replies(void)
{
    json_object *replies;

    pthread_mutex_lock(&json_lock);
    replies = json_object_new_object();
    pthread_mutex_unlock(&json_lock);

    return replies;
}

void
add_reply(json_object *replies, json_object *reply, unsigned int session_key)
{
    char *str;

    asprintf(&str, "%u", session_key);

    pthread_mutex_lock(&json_lock);
    json_object_object_add(replies, str, reply);
    pthread_mutex_unlock(&json_lock);

    free(str);
}

char *
get_param_string(json_object *data, const char *name)
{
    json_object *js_tmp = NULL;
    char *res = NULL;
    if (json_object_object_get_ex(data, name, &js_tmp) == TRUE) {
        res = strdup(json_object_get_string(js_tmp));
    }
    return res;
}

json_object *
handle_op_connect(json_object *request)
{
    char *host = NULL;
    char *port = NULL;
    char *user = NULL;
    char *pass = NULL;
    char *privkey = NULL;
    json_object *reply = NULL;
    unsigned int session_key = 0;

    DEBUG("Request: connect");
    pthread_mutex_lock(&json_lock);

    host = get_param_string(request, "host");
    port = get_param_string(request, "port");
    user = get_param_string(request, "user");
    pass = get_param_string(request, "pass");
    privkey = get_param_string(request, "privatekey");

    pthread_mutex_unlock(&json_lock);

    if (host == NULL) {
        host = "localhost";
    }

    DEBUG("host: %s, port: %s, user: %s", host, port, user);
    if (user == NULL) {
        ERROR("Cannot connect - insufficient input.");
        session_key = 0;
    } else {
        session_key = netconf_connect(host, port, user, pass, privkey);
        DEBUG("Session key: %u", session_key);
    }

    GETSPEC_ERR_REPLY

    pthread_mutex_lock(&json_lock);
    if (session_key == 0) {
        /* negative reply */
        if (err_reply == NULL) {
            reply = json_object_new_object();
            json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
            json_object_object_add(reply, "error-message", json_object_new_string("Connecting NETCONF server failed."));
            ERROR("Connection failed.");
        } else {
            /* use filled err_reply from libnetconf's callback */
            reply = err_reply;
            ERROR("Connect - error from libnetconf's callback.");
        }
    } else {
        /* positive reply */
        reply = json_object_new_object();
        json_object_object_add(reply, "type", json_object_new_int(REPLY_OK));
        json_object_object_add(reply, "session", json_object_new_int(session_key));
    }
    memset(pass, 0, strlen(pass));
    pthread_mutex_unlock(&json_lock);
    CHECK_AND_FREE(host);
    CHECK_AND_FREE(user);
    CHECK_AND_FREE(port);
    CHECK_AND_FREE(pass);
    CHECK_AND_FREE(privkey);
    return reply;
}

json_object *
handle_op_disconnect(json_object *UNUSED(request), unsigned int session_key)
{
    json_object *reply;

    DEBUG("Request: disconnect (session %u)", session_key);

    if (netconf_close(session_key, &reply) != EXIT_SUCCESS) {
        CHECK_ERR_SET_REPLY_ERR("Get configuration information from device failed.")
    } else {
        reply = create_ok_reply();
    }

    return reply;
}

json_object *
handle_op_get(json_object *request, unsigned int session_key)
{
    char *filter = NULL;
    char *data = NULL;
    json_object *reply = NULL, *obj;
    int strict;

    DEBUG("Request: get (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    filter = get_param_string(request, "filter");
    if (json_object_object_get_ex(request, "strict", &obj) == FALSE) {
        pthread_mutex_unlock(&json_lock);
        reply = create_error_reply("Missing strict parameter.");
        return reply;
    }
    strict = json_object_get_boolean(obj);
    pthread_mutex_unlock(&json_lock);

    if ((data = netconf_get(session_key, filter, strict, &reply)) == NULL) {
        CHECK_ERR_SET_REPLY_ERR("Get information failed.")
    } else {
        reply = create_data_reply(data);
        free(data);
    }

    return reply;
}

json_object *
handle_op_getconfig(json_object *request, unsigned int session_key)
{
    NC_DATASTORE ds_type_s = -1;
    char *filter = NULL;
    char *data = NULL;
    char *source = NULL;
    json_object *reply = NULL, *obj;
    int strict;

    DEBUG("Request: get-config (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    filter = get_param_string(request, "filter");
    source = get_param_string(request, "source");
    if (source != NULL) {
        ds_type_s = parse_datastore(source);
    }
    if (json_object_object_get_ex(request, "strict", &obj) == FALSE) {
        pthread_mutex_unlock(&json_lock);
        reply = create_error_reply("Missing strict parameter.");
        return reply;
    }
    strict = json_object_get_boolean(obj);
    pthread_mutex_unlock(&json_lock);

    if ((int)ds_type_s == -1) {
        reply = create_error_reply("Invalid source repository type requested.");
        goto finalize;
    }

    if ((data = netconf_getconfig(session_key, ds_type_s, filter, strict, &reply)) == NULL) {
        CHECK_ERR_SET_REPLY_ERR("Get configuration operation failed.")
    } else {
        reply = create_data_reply(data);
        free(data);
    }

finalize:
    CHECK_AND_FREE(filter);
    CHECK_AND_FREE(source);
    return reply;
}

json_object *
handle_op_editconfig(json_object *request, unsigned int session_key, int idx)
{
    NC_DATASTORE ds_type_t = -1;
    NC_RPC_EDIT_DFLTOP defop_type = 0;
    NC_RPC_EDIT_ERROPT erropt_type = 0;
    NC_RPC_EDIT_TESTOPT testopt_type = NC_RPC_EDIT_TESTOPT_TESTSET;
    char *defop = NULL;
    char *erropt = NULL;
    char *config = NULL;
    char *target = NULL;
    char *testopt = NULL;
    char *urisource = NULL;
    json_object *reply = NULL, *configs, *obj;
    struct lyd_node *content;
    struct session_with_mutex *locked_session;

    DEBUG("Request: edit-config (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    /* get parameters */
    if (json_object_object_get_ex(request, "configs", &configs) == FALSE) {
        pthread_mutex_unlock(&json_lock);
        reply = create_error_reply("Missing configs parameter.");
        goto finalize;
    }
    obj = json_object_array_get_idx(configs, idx);
    config = strdup(json_object_get_string(obj));

    target = get_param_string(request, "target");
    defop = get_param_string(request, "default-operation");
    erropt = get_param_string(request, "error-option");
    urisource = get_param_string(request, "uri-source");
    testopt = get_param_string(request, "test-option");
    pthread_mutex_unlock(&json_lock);

    if (target != NULL) {
        ds_type_t = parse_datastore(target);
    }

    if (defop != NULL) {
        if (strcmp(defop, "merge") == 0) {
            defop_type = NC_RPC_EDIT_DFLTOP_MERGE;
        } else if (strcmp(defop, "replace") == 0) {
            defop_type = NC_RPC_EDIT_DFLTOP_REPLACE;
        } else if (strcmp(defop, "none") == 0) {
            defop_type = NC_RPC_EDIT_DFLTOP_NONE;
        } else {
            reply = create_error_reply("Invalid default-operation parameter.");
            goto finalize;
        }
    } else {
        defop_type = NC_RPC_EDIT_DFLTOP_UNKNOWN;
    }

    if (erropt != NULL) {
        if (strcmp(erropt, "continue-on-error") == 0) {
            erropt_type = NC_RPC_EDIT_ERROPT_CONTINUE;
        } else if (strcmp(erropt, "stop-on-error") == 0) {
            erropt_type = NC_RPC_EDIT_ERROPT_STOP;
        } else if (strcmp(erropt, "rollback-on-error") == 0) {
            erropt_type = NC_RPC_EDIT_ERROPT_ROLLBACK;
        } else {
            reply = create_error_reply("Invalid error-option parameter.");
            goto finalize;
        }
    } else {
        erropt_type = 0;
    }

    if ((config && urisource) || (!config && !urisource)) {
        reply = create_error_reply("Invalid config and uri-source data parameters.");
        goto finalize;
    }

    if (config) {
        locked_session = session_get_locked(session_key, NULL);
        if (!locked_session) {
            ERROR("Unknown session or locking failed.");
            goto finalize;
        }

        content = lyd_parse_mem(nc_session_get_ctx(locked_session->session), config, LYD_JSON, LYD_OPT_EDIT);
        session_unlock(locked_session);

        free(config);
        lyd_print_mem(&config, content, LYD_XML, LYP_WITHSIBLINGS);
        lyd_free_withsiblings(content);
    } else {
        config = urisource;
    }

    if (testopt != NULL) {
        testopt_type = parse_testopt(testopt);
    } else {
        testopt_type = NC_RPC_EDIT_TESTOPT_TESTSET;
    }

    reply = netconf_editconfig(session_key, ds_type_t, defop_type, erropt_type, testopt_type, config);

    CHECK_ERR_SET_REPLY

finalize:
    CHECK_AND_FREE(defop);
    CHECK_AND_FREE(erropt);
    CHECK_AND_FREE(config);
    CHECK_AND_FREE(urisource);
    CHECK_AND_FREE(target);
    CHECK_AND_FREE(testopt);

    return reply;
}

json_object *
handle_op_copyconfig(json_object *request, unsigned int session_key, int idx)
{
    NC_DATASTORE ds_type_s = -1;
    NC_DATASTORE ds_type_t = -1;
    char *config = NULL;
    char *target = NULL;
    char *source = NULL;
    char *uri_src = NULL;
    char *uri_trg = NULL;
    json_object *reply = NULL, *configs, *obj;
    struct lyd_node *content;
    struct session_with_mutex *locked_session;

    DEBUG("Request: copy-config (session %u)", session_key);

    /* get parameters */
    pthread_mutex_lock(&json_lock);
    target = get_param_string(request, "target");
    source = get_param_string(request, "source");
    uri_src = get_param_string(request, "uri-source");
    uri_trg = get_param_string(request, "uri-target");
    if (!strcmp(source, "config")) {
        if (json_object_object_get_ex(request, "configs", &configs) == FALSE) {
            pthread_mutex_unlock(&json_lock);
            reply = create_error_reply("Missing configs parameter.");
            goto finalize;
        }
        obj = json_object_array_get_idx(configs, idx);
        if (!obj) {
            pthread_mutex_unlock(&json_lock);
            reply = create_error_reply("Configs array parameter shorter than sessions.");
            goto finalize;
        }
        config = strdup(json_object_get_string(obj));
    }
    pthread_mutex_unlock(&json_lock);

    if (target != NULL) {
        ds_type_t = parse_datastore(target);
    }
    if (source != NULL) {
        ds_type_s = parse_datastore(source);
    }

    if ((int)ds_type_s == -1) {
        /* invalid source datastore specified */
        reply = create_error_reply("Invalid source repository type requested.");
        goto finalize;
    }

    if ((int)ds_type_t == -1) {
        /* invalid target datastore specified */
        reply = create_error_reply("Invalid target repository type requested.");
        goto finalize;
    }

    if (ds_type_s == NC_DATASTORE_URL) {
        if (uri_src == NULL) {
            uri_src = "";
        }
    }
    if (ds_type_t == NC_DATASTORE_URL) {
        if (uri_trg == NULL) {
            uri_trg = "";
        }
    }

    if (config) {
        locked_session = session_get_locked(session_key, NULL);
        if (!locked_session) {
            ERROR("Unknown session or locking failed.");
            goto finalize;
        }

        content = lyd_parse_mem(nc_session_get_ctx(locked_session->session), config, LYD_JSON, LYD_OPT_CONFIG);
        session_unlock(locked_session);

        free(config);
        lyd_print_mem(&config, content, LYD_XML, LYP_WITHSIBLINGS);
        lyd_free_withsiblings(content);
    }

    reply = netconf_copyconfig(session_key, ds_type_s, ds_type_t, config, uri_src, uri_trg);

    CHECK_ERR_SET_REPLY

finalize:
    CHECK_AND_FREE(config);
    CHECK_AND_FREE(target);
    CHECK_AND_FREE(source);
    CHECK_AND_FREE(uri_src);
    CHECK_AND_FREE(uri_trg);

    return reply;
}

json_object *
handle_op_deleteconfig(json_object *request, unsigned int session_key)
{
    json_object *reply;
    NC_DATASTORE ds_type = -1;
    char *target, *url;

    DEBUG("Request: delete-config (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    target = get_param_string(request, "target");
    url = get_param_string(request, "url");
    pthread_mutex_unlock(&json_lock);

    if (target != NULL) {
        ds_type = parse_datastore(target);
    }
    if ((int)ds_type == -1) {
        reply = create_error_reply("Invalid target repository type requested.");
        goto finalize;
    }
    if (ds_type == NC_DATASTORE_URL) {
        if (!url) {
            url = "";
        }
    }

    reply = netconf_deleteconfig(session_key, ds_type, url);

    CHECK_ERR_SET_REPLY
    if (reply == NULL) {
        reply = create_ok_reply();
    }

finalize:
    CHECK_AND_FREE(target);
    CHECK_AND_FREE(url);
    return reply;
}

json_object *
handle_op_lock(json_object *request, unsigned int session_key)
{
    json_object *reply;
    NC_DATASTORE ds_type = -1;
    char *target;

    DEBUG("Request: lock (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    target = get_param_string(request, "target");
    pthread_mutex_unlock(&json_lock);

    if (target != NULL) {
        ds_type = parse_datastore(target);
    }
    if ((int)ds_type == -1) {
        reply = create_error_reply("Invalid target repository type requested.");
        goto finalize;
    }

    reply = netconf_lock(session_key, ds_type);

    CHECK_ERR_SET_REPLY
    if (reply == NULL) {
        reply = create_ok_reply();
    }

finalize:
    CHECK_AND_FREE(target);
    return reply;
}

json_object *
handle_op_unlock(json_object *request, unsigned int session_key)
{
    json_object *reply;
    NC_DATASTORE ds_type = -1;
    char *target;

    DEBUG("Request: unlock (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    target = get_param_string(request, "target");
    pthread_mutex_unlock(&json_lock);

    if (target != NULL) {
        ds_type = parse_datastore(target);
    }
    if ((int)ds_type == -1) {
        reply = create_error_reply("Invalid target repository type requested.");
        goto finalize;
    }

    reply = netconf_unlock(session_key, ds_type);

    CHECK_ERR_SET_REPLY
    if (reply == NULL) {
        reply = create_ok_reply();
    }

finalize:
    CHECK_AND_FREE(target);
    return reply;
}

json_object *
handle_op_kill(json_object *request, unsigned int session_key)
{
    json_object *reply = NULL;
    char *sid = NULL;

    DEBUG("Request: kill-session (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    sid = get_param_string(request, "session-id");
    pthread_mutex_unlock(&json_lock);

    if (sid == NULL) {
        reply = create_error_reply("Missing session-id parameter.");
        goto finalize;
    }

    reply = netconf_killsession(session_key, sid);

    CHECK_ERR_SET_REPLY

finalize:
    CHECK_AND_FREE(sid);
    return reply;
}

json_object *
handle_op_info(json_object *UNUSED(request), unsigned int session_key)
{
    json_object *reply = NULL;
    struct session_with_mutex *locked_session = NULL;
    DEBUG("Request: get info about session %u", session_key);

    DEBUG("LOCK wrlock %s", __func__);
    if (pthread_rwlock_rdlock(&session_lock) != 0) {
        ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
    }

    for (locked_session = netconf_sessions_list;
         locked_session && (locked_session->session_key != session_key);
         locked_session = locked_session->next);
    if (locked_session != NULL) {
        DEBUG("LOCK mutex %s", __func__);
        pthread_mutex_lock(&locked_session->lock);
        DEBUG("UNLOCK wrlock %s", __func__);
        if (pthread_rwlock_unlock(&session_lock) != 0) {
            ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
        }
        if (locked_session->hello_message != NULL) {
            reply = locked_session->hello_message;
        } else {
            reply = create_error_reply("Invalid session identifier.");
        }
        DEBUG("UNLOCK mutex %s", __func__);
        pthread_mutex_unlock(&locked_session->lock);
    } else {
        DEBUG("UNLOCK wrlock %s", __func__);
        if (pthread_rwlock_unlock(&session_lock) != 0) {
            ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
        }
        reply = create_error_reply("Invalid session identifier.");
    }

    return reply;
}

json_object *
handle_op_generic(json_object *request, unsigned int session_key, int idx)
{
    json_object *reply = NULL, *contents, *obj;
    char *content = NULL, *str;
    struct lyd_node *data = NULL, *node_content;
    struct session_with_mutex *locked_session;

    DEBUG("Request: generic request (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    if (json_object_object_get_ex(request, "contents", &contents) == FALSE) {
        pthread_mutex_unlock(&json_lock);
        reply = create_error_reply("Missing contents parameter.");
        goto finalize;
    }
    obj = json_object_array_get_idx(contents, idx);
    if (!obj) {
        pthread_mutex_unlock(&json_lock);
        reply = create_error_reply("Contents array parameter shorter than sessions.");
        goto finalize;
    }
    content = strdup(json_object_get_string(obj));
    pthread_mutex_unlock(&json_lock);

    locked_session = session_get_locked(session_key, NULL);
    if (!locked_session) {
        ERROR("Unknown session or locking failed.");
        goto finalize;
    }

    node_content = lyd_parse_mem(nc_session_get_ctx(locked_session->session), content, LYD_JSON, LYD_OPT_RPC);
    session_unlock(locked_session);

    free(content);
    lyd_print_mem(&content, node_content, LYD_XML, LYP_WITHSIBLINGS);
    lyd_free_withsiblings(node_content);

    reply = netconf_generic(session_key, content, &data);
    if (reply == NULL) {
        GETSPEC_ERR_REPLY
        if (err_reply != NULL) {
            /* use filled err_reply from libnetconf's callback */
            reply = err_reply;
        }
    } else {
        if (data == NULL) {
            pthread_mutex_lock(&json_lock);
            reply = json_object_new_object();
            json_object_object_add(reply, "type", json_object_new_int(REPLY_OK));
            pthread_mutex_unlock(&json_lock);
        } else {
            lyd_print_mem(&str, data, LYD_JSON, LYP_WITHSIBLINGS);
            lyd_free_withsiblings(data);
            reply = create_data_reply(str);
            free(str);
        }
    }

finalize:
    CHECK_AND_FREE(content);
    return reply;
}

json_object *
handle_op_getschema(json_object *request, unsigned int session_key)
{
    char *data = NULL;
    char *identifier = NULL;
    char *version = NULL;
    char *format = NULL;
    json_object *reply = NULL;

    DEBUG("Request: get-schema (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    identifier = get_param_string(request, "identifier");
    version = get_param_string(request, "version");
    format = get_param_string(request, "format");
    pthread_mutex_unlock(&json_lock);

    if (identifier == NULL) {
        reply = create_error_reply("No identifier for get-schema supplied.");
        goto finalize;
    }

    DEBUG("get-schema(version: %s, format: %s)", version, format);
    if ((data = netconf_getschema(session_key, identifier, version, format, &reply)) == NULL) {
        CHECK_ERR_SET_REPLY_ERR("Get models operation failed.")
    } else {
        reply = create_data_reply(data);
        free(data);
    }

finalize:
    CHECK_AND_FREE(identifier);
    CHECK_AND_FREE(version);
    CHECK_AND_FREE(format);
    return reply;
}

json_object *
handle_op_reloadhello(json_object *UNUSED(request), unsigned int session_key)
{
    struct nc_session *temp_session = NULL;
    struct session_with_mutex * locked_session = NULL;
    json_object *reply = NULL;

    DEBUG("Request: reload hello (session %u)", session_key);

    DEBUG("LOCK wrlock %s", __func__);
    if (pthread_rwlock_wrlock(&session_lock) != 0) {
        ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
        return NULL;
    }

    for (locked_session = netconf_sessions_list;
         locked_session && (locked_session->session_key != session_key);
         locked_session = locked_session->next);
    if ((locked_session != NULL) && (locked_session->hello_message != NULL)) {
        DEBUG("LOCK mutex %s", __func__);
        pthread_mutex_lock(&locked_session->lock);
        DEBUG("creating temporary NC session.");
        temp_session = nc_connect_ssh_channel(locked_session->session, NULL);
        if (temp_session != NULL) {
            prepare_status_message(locked_session, temp_session);
            DEBUG("closing temporal NC session.");
            nc_session_free(temp_session, NULL);
            temp_session = NULL;
        } else {
            DEBUG("Reload hello failed due to channel establishment");
            reply = create_error_reply("Reload was unsuccessful, connection failed.");
        }
        DEBUG("UNLOCK mutex %s", __func__);
        pthread_mutex_unlock(&locked_session->lock);
        DEBUG("UNLOCK wrlock %s", __func__);
        if (pthread_rwlock_unlock(&session_lock) != 0) {
            ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
        }
    } else {
        DEBUG("UNLOCK wrlock %s", __func__);
        if (pthread_rwlock_unlock(&session_lock) != 0) {
            ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
        }
        reply = create_error_reply("Invalid session identifier.");
    }

    if ((reply == NULL) && (locked_session->hello_message != NULL)) {
        reply = locked_session->hello_message;
    }

    return reply;
}

void
notification_history(struct nc_session *session, const struct nc_notif *notif)
{
    time_t eventtime;
    char *content;
    (void)session;

    eventtime = nc_datetime2time(notif->datetime);

    json_object *notif_history_array = (json_object *)pthread_getspecific(notif_history_key);
    if (notif_history_array == NULL) {
        ERROR("No list of notification history found.");
        return;
    }
    DEBUG("Got notification from history %lu.", (long unsigned)eventtime);
    pthread_mutex_lock(&json_lock);
    json_object *notif_obj = json_object_new_object();
    if (notif_obj == NULL) {
        ERROR("Could not allocate memory for notification (json).");
        goto failed;
    }
    lyd_print_mem(&content, notif->tree, LYD_JSON, 0);

    json_object_object_add(notif_obj, "eventtime", json_object_new_int64(eventtime));
    json_object_object_add(notif_obj, "content", json_object_new_string(content));

    free(content);

    json_object_array_add(notif_history_array, notif_obj);
failed:
    pthread_mutex_unlock(&json_lock);
}

json_object *
handle_op_ntfgethistory(json_object *request, unsigned int session_key)
{
    json_object *reply = NULL;
    json_object *js_tmp = NULL;
    struct session_with_mutex *locked_session = NULL;
    struct nc_session *temp_session = NULL;
    struct nc_rpc *rpc = NULL;
    time_t start = 0;
    time_t stop = 0;
    int64_t from = 0, to = 0;

    DEBUG("Request: get notification history (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    if (json_object_object_get_ex(request, "from", &js_tmp) == TRUE) {
        from = json_object_get_int64(js_tmp);
    }
    if (json_object_object_get_ex(request, "to", &js_tmp) == TRUE) {
        to = json_object_get_int64(js_tmp);
    }
    pthread_mutex_unlock(&json_lock);

    start = time(NULL) + from;
    stop = time(NULL) + to;

    DEBUG("notification history interval %li %li", (long int)from, (long int)to);

    DEBUG("LOCK wrlock %s", __func__);
    if (pthread_rwlock_rdlock(&session_lock) != 0) {
        ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
        reply = create_error_reply("Internal lock failed.");
        goto finalize;
    }

    for (locked_session = netconf_sessions_list;
         locked_session && (locked_session->session_key != session_key);
         locked_session = locked_session->next);
    if (locked_session != NULL) {
        DEBUG("LOCK mutex %s", __func__);
        pthread_mutex_lock(&locked_session->lock);
        DEBUG("UNLOCK wrlock %s", __func__);
        if (pthread_rwlock_unlock(&session_lock) != 0) {
            ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
        }
        DEBUG("creating temporal NC session.");
        temp_session = nc_connect_ssh_channel(locked_session->session, NULL);
        if (temp_session != NULL) {
            rpc = nc_rpc_subscribe(NULL, NULL, nc_time2datetime(start, NULL), nc_time2datetime(stop, NULL), NC_PARAMTYPE_CONST);
            if (rpc == NULL) {
                DEBUG("UNLOCK mutex %s", __func__);
                pthread_mutex_unlock(&locked_session->lock);
                DEBUG("notifications: creating an rpc request failed.");
                reply = create_error_reply("notifications: creating an rpc request failed.");
                goto finalize;
            }

            DEBUG("Send NC subscribe.");
            /** \todo replace with sth like netconf_op(http_server, session_hash, rpc) */
            json_object *res = netconf_unlocked_op(temp_session, rpc);
            if (res != NULL) {
                DEBUG("UNLOCK mutex %s", __func__);
                pthread_mutex_unlock(&locked_session->lock);
                DEBUG("Subscription RPC failed.");
                reply = res;
                goto finalize;
            }
            rpc = NULL; /* just note that rpc is already freed by send_recv_process() */

            DEBUG("UNLOCK mutex %s", __func__);
            pthread_mutex_unlock(&locked_session->lock);
            DEBUG("LOCK mutex %s", __func__);
            pthread_mutex_lock(&ntf_history_lock);
            pthread_mutex_lock(&json_lock);
            json_object *notif_history_array = json_object_new_array();
            pthread_mutex_unlock(&json_lock);
            if (pthread_setspecific(notif_history_key, notif_history_array) != 0) {
                ERROR("notif_history: cannot set thread-specific hash value.");
            }

            nc_recv_notif_dispatch(temp_session, notification_history);

            pthread_mutex_lock(&json_lock);
            reply = json_object_new_object();
            json_object_object_add(reply, "notifications", notif_history_array);
            //json_object_put(notif_history_array);
            pthread_mutex_unlock(&json_lock);

            DEBUG("UNLOCK mutex %s", __func__);
            pthread_mutex_unlock(&ntf_history_lock);
            DEBUG("closing temporal NC session.");
            nc_session_free(temp_session, NULL);
            temp_session = NULL;
        } else {
            DEBUG("UNLOCK mutex %s", __func__);
            pthread_mutex_unlock(&locked_session->lock);
            DEBUG("Get history of notification failed due to channel establishment");
            reply = create_error_reply("Get history of notification was unsuccessful, connection failed.");
        }
    } else {
        DEBUG("UNLOCK wrlock %s", __func__);
        if (pthread_rwlock_unlock(&session_lock) != 0) {
            ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
        }
        reply = create_error_reply("Invalid session identifier.");
    }

finalize:
    return reply;
}

json_object *
handle_op_validate(json_object *request, unsigned int session_key)
{
    json_object *reply = NULL;
    char *target = NULL;
    char *url = NULL;
    struct nc_rpc *rpc = NULL;
    NC_DATASTORE target_ds;

    DEBUG("Request: validate datastore (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    target = get_param_string(request, "target");
    url = get_param_string(request, "url");
    pthread_mutex_unlock(&json_lock);


    if (target == NULL) {
        reply = create_error_reply("Missing target parameter.");
        goto finalize;
    }

    /* validation */
    target_ds = parse_datastore(target);
    rpc = nc_rpc_validate(target_ds, url, NC_PARAMTYPE_CONST);
    if (rpc == NULL) {
        DEBUG("mod_netconf: creating rpc request failed");
        reply = create_error_reply("Creation of RPC request failed.");
        goto finalize;
    }

    if ((reply = netconf_op(session_key, rpc, 0, NULL)) == NULL) {
        CHECK_ERR_SET_REPLY

        if (reply == NULL) {
            DEBUG("Request: validation ok.");
            reply = create_ok_reply();
        }
    }
    nc_rpc_free (rpc);

finalize:
    CHECK_AND_FREE(target);
    CHECK_AND_FREE(url);
    return reply;
}

json_object *
handle_op_query(json_object *request, unsigned int session_key, int idx)
{
    json_object *reply = NULL, *filters, *obj;
    char *filter = NULL;
    int load_children = 0;

    DEBUG("Request: query (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    if (json_object_object_get_ex(request, "filters", &filters) == FALSE) {
        pthread_mutex_unlock(&json_lock);
        reply = create_error_reply("Missing filters parameter.");
        goto finalize;
    }
    obj = json_object_array_get_idx(filters, idx);
    if (!obj) {
        pthread_mutex_unlock(&json_lock);
        reply = create_error_reply("Filters array parameter shorter than sessions.");
        goto finalize;
    }
    filter = strdup(json_object_get_string(obj));
    if (json_object_object_get_ex(request, "load_children", &obj) == TRUE) {
        load_children = json_object_get_boolean(obj);
    }
    pthread_mutex_unlock(&json_lock);

    reply = libyang_query(session_key, filter, load_children);

    CHECK_ERR_SET_REPLY
    if (!reply) {
        reply = create_error_reply("Query failed.");
    }

finalize:
    CHECK_AND_FREE(filter);
    return reply;
}

json_object *
handle_op_merge(json_object *request, unsigned int session_key, int idx)
{
    json_object *reply = NULL, *configs, *obj;
    char *config = NULL;
    struct lyd_node *content;
    struct session_with_mutex *locked_session;

    DEBUG("Request: merge (session %u)", session_key);

    pthread_mutex_lock(&json_lock);
    if (json_object_object_get_ex(request, "configurations", &configs) == FALSE) {
        pthread_mutex_unlock(&json_lock);
        reply = create_error_reply("Missing configurations parameter.");
        goto finalize;
    }
    obj = json_object_array_get_idx(configs, idx);
    if (!obj) {
        pthread_mutex_unlock(&json_lock);
        reply = create_error_reply("Filters array parameter shorter than sessions.");
        goto finalize;
    }
    config = strdup(json_object_get_string(obj));
    pthread_mutex_unlock(&json_lock);

    locked_session = session_get_locked(session_key, NULL);
    if (!locked_session) {
        ERROR("Unknown session or locking failed.");
        goto finalize;
    }

    content = lyd_parse_mem(nc_session_get_ctx(locked_session->session), config, LYD_JSON, LYD_OPT_DATA);
    session_unlock(locked_session);

    free(config);
    lyd_print_mem(&config, content, LYD_XML, LYP_WITHSIBLINGS);
    lyd_free_withsiblings(content);

    reply = libyang_merge(session_key, config);

    CHECK_ERR_SET_REPLY
    if (!reply) {
        reply = create_error_reply("Merge failed.");
    }

finalize:
    CHECK_AND_FREE(config);
    return reply;
}

void *
thread_routine(void *arg)
{
    void *retval = NULL;
    struct pollfd fds;
    json_object *request = NULL, *replies = NULL, *reply, *sessions = NULL;
    json_object *js_tmp = NULL;
    int operation = (-1), count, i;
    int status = 0;
    const char *msgtext;
    unsigned int session_key = 0;
    char *chunked_out_msg = NULL;
    int client = ((struct pass_to_thread *)arg)->client;

    char *buffer = NULL;

    /* init thread specific err_reply memory */
    create_err_reply_p();

    while (!isterminated) {
        fds.fd = client;
        fds.events = POLLIN;
        fds.revents = 0;

        status = poll(&fds, 1, 1000);

        if (status == 0 || (status == -1 && (errno == EAGAIN || (errno == EINTR && isterminated == 0)))) {
            /* poll was interrupted - check if the isterminated is set and if not, try poll again */
            continue;
        } else if (status < 0) {
            /* 0:  poll time outed
             *     close socket and ignore this request from the client, it can try it again
             * -1: poll failed
             *     something wrong happend, close this socket and wait for another request
             */
            close(client);
            break;
        }
        /* status > 0 */

        /* check the status of the socket */

        /* if nothing to read and POLLHUP (EOF) or POLLERR set */
        if ((fds.revents & POLLHUP) || (fds.revents & POLLERR)) {
            /* close client's socket (it's probably already closed by client */
            close(client);
            break;
        }

        DEBUG("Get framed message...");
        buffer = get_framed_message(client);

        DEBUG("Check read buffer.");
        if (buffer != NULL) {
            enum json_tokener_error jerr;
            pthread_mutex_lock(&json_lock);
            request = json_tokener_parse_verbose(buffer, &jerr);
            if (jerr != json_tokener_success) {
                ERROR("JSON parsing error");
                pthread_mutex_unlock(&json_lock);
                continue;
            }

            if (json_object_object_get_ex(request, "type", &js_tmp) == TRUE) {
                operation = json_object_get_int(js_tmp);
            }
            pthread_mutex_unlock(&json_lock);
            if (operation == -1) {
                replies = create_replies();
                add_reply(replies, create_error_reply("Missing operation type from frontend."), 0);
                goto send_reply;
            }

            if ((operation < 4) || ((operation > 19) && (operation < 100)) || (operation > 101)) {
                DEBUG("Unknown mod_netconf operation requested (%d)", operation);
                replies = create_replies();
                add_reply(replies, create_error_reply("Operation not supported."), 0);
                goto send_reply;
            }

            DEBUG("operation %d", operation);

            /* null global JSON error-reply */
            clean_err_reply();

            /* clean replies envelope */
            if (replies != NULL) {
                pthread_mutex_lock(&json_lock);
                json_object_put(replies);
                pthread_mutex_unlock(&json_lock);
            }
            replies = create_replies();

            if (operation == MSG_CONNECT) {
                count = 1;
            } else {
                pthread_mutex_lock(&json_lock);
                if (json_object_object_get_ex(request, "sessions", &sessions) == FALSE) {
                    add_reply(replies, create_error_reply("Operation missing \"sessions\" arg"), 0);
                    goto send_reply;
                }
                count = json_object_array_length(sessions);
                pthread_mutex_unlock(&json_lock);
            }

            for (i = 0; i < count; ++i) {
                if (operation != MSG_CONNECT) {
                    js_tmp = json_object_array_get_idx(sessions, i);
                    session_key = json_object_get_int(js_tmp);
                }

                /* process required operation */
                switch (operation) {
                case MSG_CONNECT:
                    reply = handle_op_connect(request);
                    break;
                case MSG_DISCONNECT:
                    reply = handle_op_disconnect(request, session_key);
                    break;
                case MSG_GET:
                    reply = handle_op_get(request, session_key);
                    break;
                case MSG_GETCONFIG:
                    reply = handle_op_getconfig(request, session_key);
                    break;
                case MSG_EDITCONFIG:
                    reply = handle_op_editconfig(request, session_key, i);
                    break;
                case MSG_COPYCONFIG:
                    reply = handle_op_copyconfig(request, session_key, i);
                    break;
                case MSG_DELETECONFIG:
                    reply = handle_op_deleteconfig(request, session_key);
                    break;
                case MSG_LOCK:
                    reply = handle_op_lock(request, session_key);
                    break;
                case MSG_UNLOCK:
                    reply = handle_op_unlock(request, session_key);
                    break;
                case MSG_KILL:
                    reply = handle_op_kill(request, session_key);
                    break;
                case MSG_INFO:
                    reply = handle_op_info(request, session_key);
                    break;
                case MSG_GENERIC:
                    reply = handle_op_generic(request, session_key, i);
                    break;
                case MSG_GETSCHEMA:
                    reply = handle_op_getschema(request, session_key);
                    break;
                case MSG_RELOADHELLO:
                    reply = handle_op_reloadhello(request, session_key);
                    break;
                case MSG_NTF_GETHISTORY:
                    reply = handle_op_ntfgethistory(request, session_key);
                    break;
                case MSG_VALIDATE:
                    reply = handle_op_validate(request, session_key);
                    break;
                case SCH_QUERY:
                    reply = handle_op_query(request, session_key, i);
                    break;
                case SCH_MERGE:
                    reply = handle_op_merge(request, session_key, i);
                    break;
                }

                add_reply(replies, reply, session_key);
            }

            /* free parameters */
            operation = (-1);

            DEBUG("Clean request json object.");
            if (request != NULL) {
                pthread_mutex_lock(&json_lock);
                json_object_put(request);
                pthread_mutex_unlock(&json_lock);
            }
            DEBUG("Send reply json object.");

send_reply:
            /* send reply to caller */
            if (replies) {
                pthread_mutex_lock(&json_lock);
                msgtext = json_object_to_json_string(replies);
                if (asprintf(&chunked_out_msg, "\n#%d\n%s\n##\n", (int)strlen(msgtext), msgtext) == -1) {
                    if (buffer != NULL) {
                        free(buffer);
                        buffer = NULL;
                    }
                    pthread_mutex_unlock(&json_lock);
                    break;
                }
                pthread_mutex_unlock(&json_lock);

                DEBUG("Send framed reply json object.");
                send(client, chunked_out_msg, strlen(chunked_out_msg) + 1, 0);
                DEBUG("Clean reply json object.");
                pthread_mutex_lock(&json_lock);
                json_object_put(replies);
                replies = NULL;
                DEBUG("Clean message buffer.");
                CHECK_AND_FREE(chunked_out_msg);
                chunked_out_msg = NULL;
                if (buffer) {
                    free(buffer);
                    buffer = NULL;
                }
                pthread_mutex_unlock(&json_lock);
                clean_err_reply();
            } else {
                ERROR("Reply is NULL, shouldn't be...");
                continue;
            }
        }
    }
    free(arg);
    free_err_reply();

    return retval;
}

/**
 * \brief Close all open NETCONF sessions.
 *
 * During termination of mod_netconf, it is useful to close all remaining
 * sessions. This function iterates over the list of sessions and close them
 * all.
 */
static void
close_all_nc_sessions(void)
{
    struct session_with_mutex *locked_session, *next_session;
    int ret;

    /* get exclusive access to sessions_list (conns) */
    DEBUG("LOCK wrlock %s", __func__);
    if ((ret = pthread_rwlock_wrlock (&session_lock)) != 0) {
        ERROR("Error while locking rwlock: %d (%s)", ret, strerror(ret));
        return;
    }
    for (next_session = netconf_sessions_list; next_session;) {
        locked_session = next_session;
        next_session = locked_session->next;

        /* close_and_free_session handles locking on its own */
        DEBUG("Closing NETCONF session %u (SID %u).", locked_session->session_key, nc_session_get_id(locked_session->session));
        close_and_free_session(locked_session);
    }
    netconf_sessions_list = NULL;

    /* get exclusive access to sessions_list (conns) */
    DEBUG("UNLOCK wrlock %s", __func__);
    if (pthread_rwlock_unlock (&session_lock) != 0) {
        ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
    }
}

static void
check_timeout_and_close(void)
{
    struct nc_session *ns = NULL;
    struct session_with_mutex *locked_session = NULL;
    time_t current_time = time(NULL);
    int ret;

    /* get exclusive access to sessions_list (conns) */
    if ((ret = pthread_rwlock_wrlock(&session_lock)) != 0) {
        DEBUG("Error while locking rwlock: %d (%s)", ret, strerror(ret));
        return;
    }
    for (locked_session = netconf_sessions_list; locked_session; locked_session = locked_session->next) {
        ns = locked_session->session;
        if (ns == NULL) {
            continue;
        }
        pthread_mutex_lock(&locked_session->lock);
        if ((current_time - locked_session->last_activity) > ACTIVITY_TIMEOUT) {
            DEBUG("Closing NETCONF session %u (SID %u).", locked_session->session_key, nc_session_get_id(locked_session->session));

            /* close_and_free_session handles locking on its own */
            close_and_free_session(locked_session);
        } else {
            pthread_mutex_unlock(&locked_session->lock);
        }
    }
    /* get exclusive access to sessions_list (conns) */
    if (pthread_rwlock_unlock(&session_lock) != 0) {
        ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
    }
}


/**
 * This is actually implementation of NETCONF client
 * - requests are received from UNIX socket in the predefined format
 * - results are replied through the same way
 * - the daemon run as a separate process
 *
 */
static void
forked_proc(void)
{
    struct timeval tv;
    struct sockaddr_un local, remote;
    int lsock, client, ret, i, pthread_count = 0;
    unsigned int olds = 0, timediff = 0;
    socklen_t len;
    struct pass_to_thread *arg;
    pthread_t *ptids = calloc(1, sizeof(pthread_t));
    struct timespec maxtime;
    pthread_rwlockattr_t lock_attrs;
    #ifdef WITH_NOTIFICATIONS
    char use_notifications = 0;
    #endif

    /* wait at most 5 seconds for every thread to terminate */
    maxtime.tv_sec = 5;
    maxtime.tv_nsec = 0;

#ifdef HAVE_UNIXD_SETUP_CHILD
    /* change uid and gid of process for security reasons */
    unixd_setup_child();
#else
# ifdef SU_GROUP
    if (strlen(SU_GROUP) > 0) {
        struct group *g = getgrnam(SU_GROUP);
        if (g == NULL) {
            ERROR("GID (%s) was not found.", SU_GROUP);
            return;
        }
        if (setgid(g->gr_gid) != 0) {
            ERROR("Switching to %s GID failed. (%s)", SU_GROUP, strerror(errno));
            return;
        }
    }
# else
    DEBUG("no SU_GROUP");
# endif
# ifdef SU_USER
    if (strlen(SU_USER) > 0) {
        struct passwd *p = getpwnam(SU_USER);
        if (p == NULL) {
            ERROR("UID (%s) was not found.", SU_USER);
            return;
        }
        if (setuid(p->pw_uid) != 0) {
            ERROR("Switching to UID %s failed. (%s)", SU_USER, strerror(errno));
            return;
        }
    }
# else
    DEBUG("no SU_USER");
# endif
#endif

    /* try to remove if exists */
    unlink(sockname);

    /* create listening UNIX socket to accept incoming connections */
    if ((lsock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
        ERROR("Creating socket failed (%s)", strerror(errno));
        goto error_exit;
    }

    local.sun_family = AF_UNIX;
    strncpy(local.sun_path, sockname, sizeof(local.sun_path));
    len = offsetof(struct sockaddr_un, sun_path) + strlen(local.sun_path);

    if (bind(lsock, (struct sockaddr *)&local, len) == -1) {
        if (errno == EADDRINUSE) {
            ERROR("mod_netconf socket address already in use");
            goto error_exit;
        }
        ERROR("Binding socket failed (%s)", strerror(errno));
        goto error_exit;
    }

    if (listen(lsock, MAX_SOCKET_CL) == -1) {
        ERROR("Setting up listen socket failed (%s)", strerror(errno));
        goto error_exit;
    }
    chmod(sockname, S_IWUSR | S_IWGRP | S_IWOTH | S_IRUSR | S_IRGRP | S_IROTH);

    uid_t user = -1;
    if (strlen(CHOWN_USER) > 0) {
        struct passwd *p = getpwnam(CHOWN_USER);
        if (p != NULL) {
            user = p->pw_uid;
        }
    }
    gid_t group = -1;
    if (strlen(CHOWN_GROUP) > 0) {
        struct group *g = getgrnam(CHOWN_GROUP);
        if (g != NULL) {
            group = g->gr_gid;
        }
    }
    if (chown(sockname, user, group) == -1) {
        ERROR("Chown on socket file failed (%s).", strerror(errno));
    }

    /* prepare internal lists */

    #ifdef WITH_NOTIFICATIONS
    if (notification_init() == -1) {
        ERROR("libwebsockets initialization failed");
        use_notifications = 0;
    } else {
        use_notifications = 1;
    }
    #endif

    /* setup libnetconf's callbacks */
    nc_verbosity(NC_VERB_DEBUG);
    nc_set_print_clb(clb_print);
    nc_client_ssh_set_auth_hostkey_check_clb(netconf_callback_ssh_hostkey_check);
    nc_client_ssh_set_auth_interactive_clb(netconf_callback_sshauth_interactive);
    nc_client_ssh_set_auth_password_clb(netconf_callback_sshauth_password);
    nc_client_ssh_set_auth_privkey_passphrase_clb(netconf_callback_sshauth_passphrase);

    /* disable publickey authentication */
    nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, -1);

    /* create mutex protecting session list */
    pthread_rwlockattr_init(&lock_attrs);
    /* rwlock is shared only with threads in this process */
    pthread_rwlockattr_setpshared(&lock_attrs, PTHREAD_PROCESS_PRIVATE);
    /* create rw lock */
    if (pthread_rwlock_init(&session_lock, &lock_attrs) != 0) {
        ERROR("Initialization of mutex failed: %d (%s)", errno, strerror(errno));
        goto error_exit;
    }
    pthread_mutex_init(&ntf_history_lock, NULL);
    pthread_mutex_init(&json_lock, NULL);
    DEBUG("Initialization of notification history.");
    if (pthread_key_create(&notif_history_key, NULL) != 0) {
        ERROR("Initialization of notification history failed.");
    }
    if (pthread_key_create(&err_reply_key, NULL) != 0) {
        ERROR("Initialization of reply key failed.");
    }

    fcntl(lsock, F_SETFL, fcntl(lsock, F_GETFL, 0) | O_NONBLOCK);
    while (isterminated == 0) {
        gettimeofday(&tv, NULL);
        timediff = (unsigned int)tv.tv_sec - olds;
        #ifdef WITH_NOTIFICATIONS
        if (use_notifications == 1) {
            notification_handle();
        }
        #endif
        if (timediff > ACTIVITY_CHECK_INTERVAL) {
            check_timeout_and_close();
        }

        /* open incoming connection if any */
        len = sizeof(remote);
        client = accept(lsock, (struct sockaddr *) &remote, &len);
        if (client == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
            usleep(SLEEP_TIME * 1000);
            continue;
        } else if (client == -1 && (errno == EINTR)) {
            continue;
        } else if (client == -1) {
            ERROR("Accepting mod_netconf client connection failed (%s)", strerror(errno));
            continue;
        }

        /* set client's socket as non-blocking */
        //fcntl(client, F_SETFL, fcntl(client, F_GETFL, 0) | O_NONBLOCK);

        arg = malloc(sizeof(struct pass_to_thread));
        arg->client = client;
        arg->netconf_sessions_list = netconf_sessions_list;

        /* start new thread. It will serve this particular request and then terminate */
        if ((ret = pthread_create (&ptids[pthread_count], NULL, thread_routine, (void *)arg)) != 0) {
            ERROR("Creating POSIX thread failed: %d\n", ret);
        } else {
            DEBUG("Thread %lu created", ptids[pthread_count]);
            pthread_count++;
            ptids = realloc (ptids, sizeof(pthread_t) * (pthread_count+1));
            ptids[pthread_count] = 0;
        }

        /* check if some thread already terminated, free some resources by joining it */
        for (i = 0; i < pthread_count; i++) {
            if (pthread_tryjoin_np(ptids[i], (void **)&arg) == 0) {
                DEBUG("Thread %lu joined with retval %p", ptids[i], arg);
                pthread_count--;
                if (pthread_count > 0) {
                    /* place last Thread ID on the place of joined one */
                    ptids[i] = ptids[pthread_count];
                }
            }
        }
        DEBUG("Running %d threads", pthread_count);
    }

    DEBUG("mod_netconf terminating...");
    /* join all threads */
    for (i = 0; i < pthread_count; i++) {
        pthread_timedjoin_np(ptids[i], (void **)&arg, &maxtime);
    }

    #ifdef WITH_NOTIFICATIONS
    notification_close();
    #endif

    /* close all NETCONF sessions */
    close_all_nc_sessions();

    /* destroy rwlock */
    pthread_rwlock_destroy(&session_lock);
    pthread_rwlockattr_destroy(&lock_attrs);

    DEBUG("Exiting from the mod_netconf daemon");

    free(ptids);
    close(lsock);
    exit(0);
    return;

error_exit:
    close(lsock);
    free(ptids);
    return;
}

int
main(int argc, char **argv)
{
    struct sigaction action;
    sigset_t block_mask;
    int daemonize = 0, i;

    if (argc > 3) {
        printf("Usage: [--(h)elp] [--(d)aemon] [socket-path]\n");
        return 1;
    }

    sockname = SOCKET_FILENAME;
    for (i = 1; i < argc; ++i) {
        if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
            printf("Usage: [--(h)elp] [--(d)aemon] [socket-path]\n");
            return 0;
        } else if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--daemon")) {
            daemonize = 1;
        } else {
            sockname = argv[i];
        }
    }

    if (daemonize && (daemon(0, 0) == -1)) {
        ERROR("daemon() failed (%s)", strerror(errno));
        return 1;
    }

    sigfillset(&block_mask);
    action.sa_handler = signal_handler;
    action.sa_mask = block_mask;
    action.sa_flags = 0;
    sigaction(SIGINT, &action, NULL);
    sigaction(SIGTERM, &action, NULL);

    forked_proc();
    DEBUG("Terminated");
    return 0;
}
