/**
 * @file server_config_ts.c
 * @author Roman Janota <janota@cesnet.cz>
 * @brief libnetconf2 truststore configuration functions
 *
 * @copyright
 * Copyright (c) 2023 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#define _GNU_SOURCE

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

#include "compat.h"
#include "libnetconf.h"
#include "server_config_p.h"

extern struct nc_server_opts server_opts;

/**
 * @brief Get the pointer to a certificate bag structure based on node's location in the YANG data.
 *
 * @param[in] node Node from which the certificate bag containing this node is derived.
 * @param[out] cbag Certificate bag containing the node.
 * @return 0 on success, 1 on error.
 */
static int
nc_server_config_get_certificate_bag(const struct lyd_node *node, struct nc_certificate_bag **cbag)
{
    uint16_t i;
    const char *cbag_name;
    struct nc_truststore *ts;

    assert(node);

    while (node) {
        if (!strcmp(LYD_NAME(node), "certificate-bag")) {
            break;
        }
        node = lyd_parent(node);
    }

    if (!node) {
        ERR(NULL, "Node \"%s\" is not contained in a certificate-bag subtree.", LYD_NAME(node));
        return 1;
    }

    node = lyd_child(node);
    assert(!strcmp(LYD_NAME(node), "name"));
    cbag_name = lyd_get_value(node);

    ts = &server_opts.truststore;
    for (i = 0; i < ts->cert_bag_count; i++) {
        if (!strcmp(ts->cert_bags[i].name, cbag_name)) {
            *cbag = &ts->cert_bags[i];
            return 0;
        }
    }

    ERR(NULL, "Certificate bag \"%s\" was not found.", cbag_name);
    return 1;
}

/**
 * @brief Get the pointer to a certificate structure based on node's location in the YANG data.
 *
 * @param[in] node Node from which the certificate containing this node is derived.
 * @param[in] cbag Certificate bag containing the certificate.
 * @param[out] cert Certificate containing the node.
 * @return 0 on success, 1 on error.
 */
static int
nc_server_config_get_certificate(const struct lyd_node *node, const struct nc_certificate_bag *cbag, struct nc_certificate **cert)
{
    uint16_t i;
    const char *cert_name;

    assert(node);

    while (node) {
        if (!strcmp(LYD_NAME(node), "certificate")) {
            break;
        }
        node = lyd_parent(node);
    }

    if (!node) {
        ERR(NULL, "Node \"%s\" is not contained in a certificate subtree.", LYD_NAME(node));
        return 1;
    }

    node = lyd_child(node);
    assert(!strcmp(LYD_NAME(node), "name"));
    cert_name = lyd_get_value(node);

    for (i = 0; i < cbag->cert_count; i++) {
        if (!strcmp(cbag->certs[i].name, cert_name)) {
            *cert = &cbag->certs[i];
            return 0;
        }
    }

    ERR(NULL, "Certificate \"%s\" was not found.", cert_name);
    return 1;
}

/**
 * @brief Get the pointer to a public key bag structure based on node's location in the YANG data.
 *
 * @param[in] node Node from which the public key bag containing this node is derived.
 * @param[out] pbag Public key bag containing the node.
 * @return 0 on success, 1 on error.
 */
static int
nc_server_config_get_public_key_bag(const struct lyd_node *node, struct nc_public_key_bag **pbag)
{
    uint16_t i;
    const char *pbag_name;
    struct nc_truststore *ts;

    assert(node);

    while (node) {
        if (!strcmp(LYD_NAME(node), "public-key-bag")) {
            break;
        }
        node = lyd_parent(node);
    }

    if (!node) {
        ERR(NULL, "Node \"%s\" is not contained in a public-key-bag subtree.", LYD_NAME(node));
        return 1;
    }

    node = lyd_child(node);
    assert(!strcmp(LYD_NAME(node), "name"));
    pbag_name = lyd_get_value(node);

    ts = &server_opts.truststore;
    for (i = 0; i < ts->pub_bag_count; i++) {
        if (!strcmp(ts->pub_bags[i].name, pbag_name)) {
            *pbag = &ts->pub_bags[i];
            return 0;
        }
    }

    ERR(NULL, "Public key bag \"%s\" was not found.", pbag_name);
    return 1;
}

/**
 * @brief Get the pointer to a public key structure based on node's location in the YANG data.
 *
 * @param[in] node Node from which the public key containing this node is derived.
 * @param[in] pbag Public key bag containing the public key.
 * @param[out] pkey Public key containing the node.
 * @return 0 on success, 1 on error.
 */
static int
nc_server_config_get_public_key(const struct lyd_node *node, const struct nc_public_key_bag *pbag, struct nc_public_key **pkey)
{
    uint16_t i;
    const char *pkey_name;

    assert(node);

    while (node) {
        if (!strcmp(LYD_NAME(node), "public-key")) {
            if (lyd_child(node)) {
                /* check if it's not the leaf public-key, only case about the list */
                break;
            }
        }

        node = lyd_parent(node);
    }

    if (!node) {
        ERR(NULL, "Node \"%s\" is not contained in a public-key subtree.", LYD_NAME(node));
        return 1;
    }

    node = lyd_child(node);
    assert(!strcmp(LYD_NAME(node), "name"));
    pkey_name = lyd_get_value(node);

    for (i = 0; i < pbag->pubkey_count; i++) {
        if (!strcmp(pbag->pubkeys[i].name, pkey_name)) {
            *pkey = &pbag->pubkeys[i];
            return 0;
        }
    }

    ERR(NULL, "Public key \"%s\" was not found.", pkey_name);
    return 1;
}

static void
nc_server_config_ts_del_cert_data(struct nc_certificate *cert)
{
    free(cert->cert_base64);
    cert->cert_base64 = NULL;
}

static void
nc_server_config_ts_del_public_key_base64(struct nc_public_key *pkey)
{
    free(pkey->pub_base64);
    pkey->pub_base64 = NULL;
}

static void
nc_server_config_ts_del_certificate(struct nc_certificate_bag *cbag, struct nc_certificate *cert)
{
    free(cert->name);
    cert->name = NULL;

    nc_server_config_ts_del_cert_data(cert);

    cbag->cert_count--;
    if (cbag->cert_count == 0) {
        free(cbag->certs);
        cbag->certs = NULL;
    }
}

static void
nc_server_config_ts_del_public_key(struct nc_public_key_bag *pbag, struct nc_public_key *pkey)
{
    free(pkey->name);
    pkey->name = NULL;

    nc_server_config_ts_del_public_key_base64(pkey);

    pbag->pubkey_count--;
    if (pbag->pubkey_count == 0) {
        free(pbag->pubkeys);
        pbag->pubkeys = NULL;
    }
}

static void
nc_server_config_ts_del_certificate_bag(struct nc_certificate_bag *cbag)
{
    uint16_t i, cert_count;
    struct nc_truststore *ts = &server_opts.truststore;

    free(cbag->name);
    cbag->name = NULL;

    cert_count = cbag->cert_count;
    for (i = 0; i < cert_count; i++) {
        nc_server_config_ts_del_certificate(cbag, &cbag->certs[i]);
    }

    ts->cert_bag_count--;
    if (ts->cert_bag_count == 0) {
        free(ts->cert_bags);
        ts->cert_bags = NULL;
    }
}

static void
nc_server_config_ts_del_public_key_bag(struct nc_public_key_bag *pbag)
{
    uint16_t i, pubkey_count;
    struct nc_truststore *ts = &server_opts.truststore;

    free(pbag->name);
    pbag->name = NULL;

    pubkey_count = pbag->pubkey_count;
    for (i = 0; i < pubkey_count; i++) {
        nc_server_config_ts_del_public_key(pbag, &pbag->pubkeys[i]);
    }

    ts->pub_bag_count--;
    if (ts->pub_bag_count == 0) {
        free(ts->pub_bags);
        ts->pub_bags = NULL;
    }
}

static int
nc_server_config_ts_certificate_bags(const struct lyd_node *node, NC_OPERATION op)
{
    uint16_t i, cert_bag_count;
    struct nc_truststore *ts = &server_opts.truststore;

    (void) node;

    if (op == NC_OP_DELETE) {
        cert_bag_count = ts->cert_bag_count;
        for (i = 0; i < cert_bag_count; i++) {
            nc_server_config_ts_del_certificate_bag(&ts->cert_bags[i]);
        }
    }

    return 0;
}

static int
nc_server_config_ts_public_key_bags(const struct lyd_node *node, NC_OPERATION op)
{
    uint16_t i, pub_bag_count;
    struct nc_truststore *ts = &server_opts.truststore;

    (void) node;

    if (op == NC_OP_DELETE) {
        pub_bag_count = ts->pub_bag_count;
        for (i = 0; i < pub_bag_count; i++) {
            nc_server_config_ts_del_public_key_bag(&ts->pub_bags[i]);
        }
    }

    return 0;
}

int
nc_server_config_ts_truststore(const struct lyd_node *node, NC_OPERATION op)
{
    (void) node;

    if (op == NC_OP_DELETE) {
        nc_server_config_ts_certificate_bags(NULL, NC_OP_DELETE);
        nc_server_config_ts_public_key_bags(NULL, NC_OP_DELETE);
    }

    return 0;
}

static int
nc_server_config_ts_create_certificate_bag(const struct lyd_node *node)
{
    struct nc_truststore *ts = &server_opts.truststore;

    node = lyd_child(node);
    assert(!strcmp(LYD_NAME(node), "name"));

    return nc_server_config_realloc(lyd_get_value(node), (void **)&ts->cert_bags, sizeof *ts->cert_bags, &ts->cert_bag_count);
}

static int
nc_server_config_ts_certificate_bag(const struct lyd_node *node, NC_OPERATION op)
{
    struct nc_certificate_bag *bag;

    assert(!strcmp(LYD_NAME(node), "certificate-bag"));

    if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
        if (nc_server_config_ts_create_certificate_bag(node)) {
            return 1;
        }
    } else {
        if (nc_server_config_get_certificate_bag(node, &bag)) {
            return 1;
        }

        nc_server_config_ts_del_certificate_bag(bag);
    }

    return 0;
}

static int
nc_server_config_ts_create_certificate(const struct lyd_node *node, struct nc_certificate_bag *bag)
{
    node = lyd_child(node);
    assert(!strcmp(LYD_NAME(node), "name"));

    return nc_server_config_realloc(lyd_get_value(node), (void **)&bag->certs, sizeof *bag->certs, &bag->cert_count);
}

static int
nc_server_config_ts_certificate(const struct lyd_node *node, NC_OPERATION op)
{
    struct nc_certificate_bag *bag;
    struct nc_certificate *cert;

    assert(!strcmp(LYD_NAME(node), "certificate"));

    if (nc_server_config_get_certificate_bag(node, &bag)) {
        return 1;
    }

    if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
        if (nc_server_config_ts_create_certificate(node, bag)) {
            return 1;
        }
    } else {
        if (nc_server_config_get_certificate(node, bag, &cert)) {
            return 1;
        }

        nc_server_config_ts_del_certificate(bag, cert);
    }

    return 0;
}

static int
nc_server_config_ts_cert_data(const struct lyd_node *node, NC_OPERATION op)
{
    struct nc_certificate_bag *bag;
    struct nc_certificate *cert;

    if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
        if (nc_server_config_get_certificate_bag(node, &bag)) {
            return 1;
        }
        if (nc_server_config_get_certificate(node, bag, &cert)) {
            return 1;
        }

        nc_server_config_ts_del_cert_data(cert);
        cert->cert_base64 = strdup(lyd_get_value(node));
        if (!cert->cert_base64) {
            ERRMEM;
            return 1;
        }
    }

    return 0;
}

static int
nc_server_config_ts_create_public_key_bag(const struct lyd_node *node)
{
    struct nc_truststore *ts = &server_opts.truststore;

    node = lyd_child(node);
    assert(!strcmp(LYD_NAME(node), "name"));

    return nc_server_config_realloc(lyd_get_value(node), (void **)&ts->pub_bags, sizeof *ts->pub_bags, &ts->pub_bag_count);
}

static int
nc_server_config_ts_public_key_bag(const struct lyd_node *node, NC_OPERATION op)
{
    struct nc_public_key_bag *pbag;

    assert(!strcmp(LYD_NAME(node), "public-key-bag"));

    if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
        if (nc_server_config_ts_create_public_key_bag(node)) {
            return 1;
        }
    } else {
        if (nc_server_config_get_public_key_bag(node, &pbag)) {
            return 1;
        }

        nc_server_config_ts_del_public_key_bag(pbag);
    }

    return 0;
}

static int
nc_server_config_ts_create_public_key(const struct lyd_node *node, struct nc_public_key_bag *bag)
{
    node = lyd_child(node);
    assert(!strcmp(LYD_NAME(node), "name"));

    return nc_server_config_realloc(lyd_get_value(node), (void **)&bag->pubkeys, sizeof *bag->pubkeys, &bag->pubkey_count);
}

static int
nc_server_config_ts_public_key(const struct lyd_node *node, NC_OPERATION op)
{
    int ret = 0;
    struct nc_public_key_bag *bag;
    struct nc_public_key *pkey;

    if (nc_server_config_get_public_key_bag(node, &bag)) {
        ret = 1;
        goto cleanup;
    }

    if (equal_parent_name(node, 1, "public-key-bag")) {
        /* public-key list */
        if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
            ret = nc_server_config_ts_create_public_key(node, bag);
            if (ret) {
                goto cleanup;
            }
        } else {
            if (nc_server_config_get_public_key(node, bag, &pkey)) {
                ret = 1;
                goto cleanup;
            }

            nc_server_config_ts_del_public_key(bag, pkey);
        }
    } else {
        /* public-key leaf */
        if (nc_server_config_get_public_key(node, bag, &pkey)) {
            ret = 1;
            goto cleanup;
        }

        /* replace the public key */
        nc_server_config_ts_del_public_key_base64(pkey);
        pkey->pub_base64 = strdup(lyd_get_value(node));
        if (!pkey->pub_base64) {
            ERRMEM;
            ret = 1;
            goto cleanup;
        }
    }

cleanup:
    return ret;
}

static int
nc_server_config_ts_public_key_format(const struct lyd_node *node, NC_OPERATION op)
{
    const char *format;
    struct nc_public_key_bag *bag;
    struct nc_public_key *pkey;

    (void) op;

    if (nc_server_config_get_public_key_bag(node, &bag)) {
        return 1;
    }

    if (nc_server_config_get_public_key(node, bag, &pkey)) {
        return 1;
    }

    format = ((struct lyd_node_term *)node)->value.ident->name;
    if (!strcmp(format, "ssh-public-key-format")) {
        pkey->pubkey_type = NC_SSH_PUBKEY_SSH2;
    } else if (!strcmp(format, "subject-public-key-info-format")) {
        pkey->pubkey_type = NC_SSH_PUBKEY_X509;
    } else {
        ERR(NULL, "Public key format (%s) not supported.", format);
    }

    return 0;
}

int
nc_server_config_parse_truststore(const struct lyd_node *node, NC_OPERATION op)
{
    const char *name = LYD_NAME(node);

    if (!strcmp(name, "truststore")) {
        if (nc_server_config_ts_truststore(node, op)) {
            goto error;
        }
    } else if (!strcmp(name, "certificate-bags")) {
        if (nc_server_config_ts_certificate_bags(node, op)) {
            goto error;
        }
    } else if (!strcmp(name, "certificate-bag")) {
        if (nc_server_config_ts_certificate_bag(node, op)) {
            goto error;
        }
    } else if (!strcmp(name, "certificate")) {
        if (nc_server_config_ts_certificate(node, op)) {
            goto error;
        }
    } else if (!strcmp(name, "cert-data")) {
        if (nc_server_config_ts_cert_data(node, op)) {
            goto error;
        }
    } else if (!strcmp(name, "public-key-bags")) {
        if (nc_server_config_ts_public_key_bags(node, op)) {
            goto error;
        }
    } else if (!strcmp(name, "public-key-bag")) {
        if (nc_server_config_ts_public_key_bag(node, op)) {
            goto error;
        }
    } else if (!strcmp(name, "public-key")) {
        if (nc_server_config_ts_public_key(node, op)) {
            goto error;
        }
    } else if (!strcmp(name, "public-key-format")) {
        if (nc_server_config_ts_public_key_format(node, op)) {
            goto error;
        }
    }

    return 0;

error:
    ERR(NULL, "Configuring (%s) failed.", name);
    return 1;
}

int
nc_server_config_fill_truststore(const struct lyd_node *data, NC_OPERATION op)
{
    int ret = 0;
    uint32_t prev_lo;
    struct lyd_node *tree;

    /* silently search for nodes, some of them may not be present */
    prev_lo = ly_log_options(0);

    ret = lyd_find_path(data, "/ietf-truststore:truststore", 0, &tree);
    if (ret || (tree->flags & LYD_DEFAULT)) {
        VRB(NULL, "Truststore container not found in the YANG data.");
        ret = 0;
        goto cleanup;
    }

    if (nc_server_config_parse_tree(tree, op, NC_MODULE_TRUSTSTORE)) {
        ret = 1;
        goto cleanup;
    }

cleanup:
    /* reset the logging options back to what they were */
    ly_log_options(prev_lo);
    return ret;
}
