/*!
 * \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 <syslog.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;
int daemonize;

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 *message)
{
    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(yanglib);
        }

        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 */
    if (choice->dflt) {
        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;
    const struct lys_node *node;
    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);
    }

    /* top-nodes */
    node = NULL;
    array = NULL;
    while ((node = lys_getnext(node, NULL, module, LYS_GETNEXT_WITHCHOICE))) {
        if (node->nodetype & (LYS_RPC | LYS_NOTIF)) {
            continue;
        }
        if (!array) {
            array = json_object_new_array();
        }
        item = json_object_new_string(node->name);
        json_object_array_add(array, item);
    }
    if (array) {
        json_object_object_add(parent, "top-nodes", 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) {
        pthread_rwlock_unlock(&session_lock);
        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 = NULL;
    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;

    /* 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) {
            if (((struct lyd_node_anyxml *)data)->xml_struct) {
                lyxml_print_mem(&model_data, ((struct lyd_node_anyxml *)data)->value.xml, 0);
            } else {
                model_data = strdup(((struct lyd_node_anyxml *)data)->value.str);
            }
            if (!model_data) {
                ERROR("memory allocation fail (%s:%d)", __FILE__, __LINE__);
            }
        }
    }

    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:
    if (!(node->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYXML))) {
        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), NULL, 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)
{
    switch (level) {
    case NC_VERB_ERROR:
        ERROR("lib ERROR: %s", msg);
        break;
    case NC_VERB_WARNING:
        ERROR("lib WARNING: %s", msg);
        break;
    case NC_VERB_VERBOSE:
        ERROR("lib VERBOSE: %s", msg);
        break;
    case NC_VERB_DEBUG:
        DEBUG("lib DEBUG: %s", msg);
        break;
    }

    if (level == NC_VERB_ERROR) {
        /* return global error */
        netconf_callback_error_process(msg);
    }
}

/**
 * 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)
{
    json_object *reply;

    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);
    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 = NULL;

    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) {
        ERROR("Missing the target parameter.");
        goto finalize;
    }
    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);

        if (!content) {
            ERROR("Failed to parse edit-config content.");
            goto finalize;
        }

        free(config);
        config = NULL;

        lyd_print_mem(&config, content, LYD_XML, LYP_WITHSIBLINGS);
        lyd_free_withsiblings(content);
        if (!config) {
            ERROR("Failed to print edit-config content.");
            goto finalize;
        }
    } 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, sent;
    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) {
            DEBUG("Received message:\n%s\n", buffer);
            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) {
                    pthread_mutex_unlock(&json_lock);
                    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 */
                reply = NULL;
                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);
                request = NULL;
            }
            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);
                pthread_mutex_unlock(&json_lock);
                DEBUG("Sending message:\n%s\n", msgtext);
                if (asprintf(&chunked_out_msg, "\n#%d\n%s\n##\n", (int)strlen(msgtext), msgtext) == -1) {
                    if (buffer != NULL) {
                        free(buffer);
                        buffer = NULL;
                    }
                    break;
                }

                i = 0;
                sent = 0;
                count = strlen(chunked_out_msg) + 1;
                while (count && ((i = send(client, chunked_out_msg + sent, count, 0)) != -1)) {
                    sent += i;
                    count -= i;
                }
                if (i == -1) {
                    ERROR("Sending message failed (%s).", strerror(errno));
                }
                DEBUG("Clean reply json object.");
                pthread_mutex_lock(&json_lock);
                json_object_put(replies);
                pthread_mutex_unlock(&json_lock);
                replies = NULL;
                DEBUG("Clean message buffer.");
                CHECK_AND_FREE(chunked_out_msg);
                chunked_out_msg = NULL;
                if (buffer) {
                    free(buffer);
                    buffer = NULL;
                }
                clean_err_reply();
            } else {
                ERROR("Reply is NULL, shouldn't be...");
                continue;
            }
        }
    }
    free(arg);
    free_err_reply();
    nc_thread_destroy();

    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_client_init();
    nc_verbosity(NC_VERB_VERBOSE);
    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");

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

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

int
main(int argc, char **argv)
{
    struct sigaction action;
    sigset_t block_mask;
    int 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) {
        if (daemon(0, 0) == -1) {
            ERROR("daemon() failed (%s)", strerror(errno));
            return 1;
        }
        openlog("netopeerguid", LOG_PID, LOG_DAEMON);
    }

    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");
    if (daemonize) {
        closelog();
    }
    return 0;
}
