/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "agent_conn_link_route.h"
#include "agent_config_address.h"
#include "agent_config_link_route.h"
#include "route_control.h"

#include <stdio.h>
#include <inttypes.h>

const char *qdr_conn_link_route_columns[QDR_CONN_LINK_ROUTE_COLUMN_COUNT + 1] =
    {"name",
     "identity",
     "type",
     "pattern",
     "direction",
     "containerId",
     0};

const char *CONN_LINK_ROUTE_TYPE = "org.apache.qpid.dispatch.router.connection.linkRoute";


static void _insert_column_CT(qdr_link_route_t *lr, int col, qd_composed_field_t *body, bool as_map)
{
    if (as_map)
        qd_compose_insert_string(body, qdr_conn_link_route_columns[col]);

    switch(col) {
    case QDR_CONN_LINK_ROUTE_NAME:
        if (lr->name)
            qd_compose_insert_string(body, lr->name);
        else
            qd_compose_insert_null(body);
        break;

    case QDR_CONN_LINK_ROUTE_IDENTITY: {
        char id_str[100];
        snprintf(id_str, 100, "%"PRId64, lr->identity);
        qd_compose_insert_string(body, id_str);
        break;
    }

    case QDR_CONN_LINK_ROUTE_TYPE:
        qd_compose_insert_string(body, CONN_LINK_ROUTE_TYPE);
        break;

    case QDR_CONN_LINK_ROUTE_PATTERN:
        qd_compose_insert_string(body, lr->pattern);
        break;
    case QDR_CONN_LINK_ROUTE_DIRECTION:
        qd_compose_insert_string(body,
                                 lr->dir == QD_INCOMING
                                 ? "in"
                                 : "out");
        break;
    case QDR_CONN_LINK_ROUTE_CONTAINER_ID:
        if (lr->parent_conn && lr->parent_conn->connection_info) {
            if (lr->parent_conn->connection_info->container) {
                qd_compose_insert_string(body,
                                         lr->parent_conn->connection_info->container);
                break;
            }
        }
        qd_compose_insert_null(body);
        break;
    }
}


static void _write_as_list_CT(qdr_query_t *query, qdr_link_route_t *lr)
{
    qd_composed_field_t *body = query->body;

    qd_compose_start_list(body);
    int i = 0;
    while (query->columns[i] >= 0) {
        _insert_column_CT(lr, query->columns[i], body, false);
        i++;
    }
    qd_compose_end_list(body);
}


static void _write_as_map_CT(qdr_query_t *query, qdr_link_route_t *lr)
{
    qd_composed_field_t *body = query->body;
    qd_compose_start_map(body);
    for (int col = 0; col < QDR_CONN_LINK_ROUTE_COLUMN_COUNT; col++)
        _insert_column_CT(lr, col, body, true);
    qd_compose_end_map(body);
}



// get conn via identity
static qdr_connection_t *_find_conn_CT(qdr_core_t *core, uint64_t conn_id)
{
    qdr_connection_t *conn = DEQ_HEAD(core->open_connections);
    while (conn) {
        if (conn->identity == conn_id)
            break;
        conn = DEQ_NEXT(conn);
    }
    return conn;
}


// get the link route by either name or id
static qdr_link_route_t *_find_link_route_CT(qdr_connection_t *conn,
                                             qd_iterator_t *name, qd_iterator_t *identity)
{
    qdr_link_route_t *lr = NULL;

    // if both id and name provided, prefer id
    //
    if (identity) {
        char buf[64];
        uint64_t id = 0;
        assert(qd_iterator_length(identity) < sizeof(buf));
        qd_iterator_strncpy(identity, buf, sizeof(buf));
        if (sscanf(buf, "%"SCNu64, &id) != 1) {
            return NULL;
        }
        lr = DEQ_HEAD(conn->conn_link_routes);
        while (lr) {
            if (id == lr->identity)
                break;
            lr = DEQ_NEXT(lr);
        }
    } else if (name) {
        lr = DEQ_HEAD(conn->conn_link_routes);
        while (lr) {
            if (qd_iterator_equal(name, (unsigned char *)lr->name))
                break;
            lr = DEQ_NEXT(lr);
        }
    }

    return lr;
}


void qdra_conn_link_route_create_CT(qdr_core_t         *core,
                                    qd_iterator_t      *name,
                                    qdr_query_t        *query,
                                    qd_parsed_field_t  *in_body)
{
    char *pattern = NULL;

    query->status = QD_AMQP_BAD_REQUEST;

    // fail if creating via a configuration file
    if (query->in_conn == 0) {
        query->status.description = "Can only create via management CREATE";
        goto exit;
    }

    // find the associated connection
    qdr_connection_t *conn = _find_conn_CT(core, query->in_conn);
    if (!conn) {
        query->status.description = "Parent connection no longer exists";
        goto exit;
    }

    // fail if forbidden by policy
    bool allow = conn->policy_spec ? conn->policy_spec->allowDynamicLinkRoutes : true;
    if (!allow) {
        query->status = QD_AMQP_FORBIDDEN;
        goto exit;
    }

    if (!qd_parse_is_map(in_body)) {
        query->status.description = "Body of request must be a map";
        goto exit;
    }

    //
    // Extract the fields from the request
    //
    qd_parsed_field_t *pattern_field    = qd_parse_value_by_key(in_body, qdr_conn_link_route_columns[QDR_CONN_LINK_ROUTE_PATTERN]);
    qd_parsed_field_t *dir_field        = qd_parse_value_by_key(in_body, qdr_conn_link_route_columns[QDR_CONN_LINK_ROUTE_DIRECTION]);

    if (!pattern_field) {
        query->status.description = "Pattern field is required";
        goto exit;
    }

    const char *error = NULL;
    pattern = qdra_config_address_validate_pattern_CT(pattern_field, false, &error);
    if (!pattern) {
        query->status.description = error;
        goto exit;
    }

    qd_direction_t dir;
    error = qdra_link_route_direction_CT(dir_field, &dir);
    if (error) {
        query->status.description = error;
        goto exit;
    }

    qdr_link_route_t *lr = qdr_route_add_conn_route_CT(core, conn, name, pattern, dir);
    if (!lr) {
        query->status.description = "creation failed";
        goto exit;
    }

    query->status = QD_AMQP_CREATED;
    _write_as_map_CT(query, lr);

exit:
    free(pattern);
    if (query->status.status != QD_AMQP_CREATED.status) {
        qd_log(core->agent_log, QD_LOG_ERROR, "Error performing CREATE of %s: %s",
               CONN_LINK_ROUTE_TYPE, query->status.description);
        qd_compose_insert_null(query->body);  // no body map
    }
    qdr_agent_enqueue_response_CT(core, query);
}


void qdra_conn_link_route_delete_CT(qdr_core_t    *core,
                                        qdr_query_t   *query,
                                        qd_iterator_t *name,
                                        qd_iterator_t *identity)
{
    query->status = QD_AMQP_BAD_REQUEST;

    if (!name && !identity) {
        query->status.description = "No name or identity provided";
        goto exit;
    }

    // find the associated connection, if it is not present then the entity has
    // automatically been deleted (not an error)
    //
    qdr_connection_t *conn = _find_conn_CT(core, query->in_conn);
    if (!conn) {
        query->status = QD_AMQP_NO_CONTENT;
        goto exit;
    }

    // find the targetted link route
    qdr_link_route_t *lr = _find_link_route_CT(conn, name, identity);
    if (!lr) {
        query->status = QD_AMQP_NOT_FOUND;
        goto exit;
    }

    qdr_route_del_conn_route_CT(core, lr);
    query->status = QD_AMQP_NO_CONTENT;

exit:
    if (query->status.status != QD_AMQP_NO_CONTENT.status) {
        qd_log(core->agent_log, QD_LOG_ERROR, "Error performing DELETE of %s: %s",
               CONN_LINK_ROUTE_TYPE, query->status.description);
    }
    qdr_agent_enqueue_response_CT(core, query);
}


void qdra_conn_link_route_get_CT(qdr_core_t    *core,
                                     qd_iterator_t *name,
                                     qd_iterator_t *identity,
                                     qdr_query_t   *query,
                                     const char    *columns[])
{
    query->status = QD_AMQP_BAD_REQUEST;

    if (!name && !identity) {
        query->status.description = "No name or identity provided";
        goto exit;
    }

    qdr_connection_t *conn = _find_conn_CT(core, query->in_conn);
    qdr_link_route_t *lr = (conn) ? _find_link_route_CT(conn, name, identity) : NULL;

    if (!lr) {
        // Send back a 404
        query->status = QD_AMQP_NOT_FOUND;
        goto exit;
    }

    //
    // Write the columns of the linkRoute entity into the response body.
    //
    query->status = QD_AMQP_OK;
    _write_as_map_CT(query, lr);

exit:
    //
    // Enqueue the response.
    //
    qdr_agent_enqueue_response_CT(core, query);
}


void qdra_conn_link_route_get_first_CT(qdr_core_t *core, qdr_query_t *query, int offset)
{
    query->status = QD_AMQP_OK;

    qdr_connection_t *conn = _find_conn_CT(core, query->in_conn);
    if (!conn || offset >= DEQ_SIZE(conn->conn_link_routes)) {
        query->more = false;
    } else {
        // Find the lr at the offset.
        //
        qdr_link_route_t *lr = DEQ_HEAD(conn->conn_link_routes);

        if (!lr) {
            query->more = false;
            qdr_agent_enqueue_response_CT(core, query);
            return;
        }

        for (int i = 0; i < offset && lr; i++)
            lr = DEQ_NEXT(lr);
        assert(lr);

        if (lr) {
            // write the lr into the response and advance to next
            _write_as_list_CT(query, lr);
            query->next_offset = offset + 1;
            query->more = DEQ_NEXT(lr) != NULL;
        }
        else {
            query->more = false;
        }
    }
    qdr_agent_enqueue_response_CT(core, query);
}


void qdra_conn_link_route_get_next_CT(qdr_core_t *core, qdr_query_t *query)
{
    qdr_connection_t *conn = _find_conn_CT(core, query->in_conn);
    if (!conn || query->next_offset >= DEQ_SIZE(conn->conn_link_routes)) {
        query->more = false;
    } else {
        // find the lr at the offset
        //
        qdr_link_route_t *lr = DEQ_HEAD(conn->conn_link_routes);
        for (int i = 0; i < query->next_offset && lr; i++)
            lr = DEQ_NEXT(lr);

        if (lr) {
            // write response and advance to next
            _write_as_list_CT(query, lr);
            ++query->next_offset;
            query->more = DEQ_NEXT(lr) != NULL;
        } else
            query->more = false;
    }
    qdr_agent_enqueue_response_CT(core, query);
}
