/*
 *
 * 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 "AclConnectionCounter.h"
#include "Acl.h"
#include "qpid/broker/Connection.h"
#include "qpid/log/Statement.h"
#include "qpid/sys/Mutex.h"
#include "qpid/sys/SocketAddress.h"
#include <assert.h>
#include <sstream>

using namespace qpid::sys;

namespace qpid {
namespace acl {

//
// This module instantiates a broker::ConnectionObserver and limits client
// connections by counting connections per user name, per client IP address
// and per total connection count.
//


//
//
//
ConnectionCounter::ConnectionCounter(Acl& a, uint16_t nl, uint16_t hl, uint16_t tl) :
    acl(a), nameLimit(nl), hostLimit(hl), totalLimit(tl), totalCurrentConnections(0) {}

ConnectionCounter::~ConnectionCounter() {}


//
// limitApproveLH
//
// Connection creation approver. Return true only if user is under limit.
// Called with lock held.
//
bool ConnectionCounter::limitApproveLH(
    connectCountsMap_t& theMap,
    const std::string& theName,
    uint16_t theLimit,
    bool emitLog) {

    bool result(true);
    if (theLimit > 0) {
        uint16_t count;
        connectCountsMap_t::iterator eRef = theMap.find(theName);
        if (eRef != theMap.end()) {
            count = (uint16_t)(*eRef).second;
            result = count <= theLimit;
        } else {
            // Not found
            count = 0;
        }
        if (emitLog) {
            QPID_LOG(trace, "ACL ConnectionApprover IP=" << theName
                << " limit=" << theLimit
                << " curValue=" << count
                << " result=" << (result ? "allow" : "deny"));
        }
    }
    return result;
}


//
// countConnectionLH
//
// Increment the name's count in map and return an optional comparison
//  against a connection limit.
// Called with dataLock already taken.
//
bool ConnectionCounter::countConnectionLH(
    connectCountsMap_t& theMap,
    const std::string& theName,
    uint16_t theLimit,
    bool emitLog,
    bool enforceLimit) {

    bool result(true);
    uint16_t count(0);
    connectCountsMap_t::iterator eRef = theMap.find(theName);
    if (eRef != theMap.end()) {
        count = (uint16_t)(*eRef).second + 1;
        (*eRef).second = count;
    } else {
        theMap[theName] = count = 1;
    }
    if (enforceLimit) {
        result = count <= theLimit;
    }
    if (emitLog) {
        QPID_LOG(trace, "ACL ConnectionApprover user=" << theName
            << " limit=" << theLimit
            << " curValue=" << count
            << " result=" << (result ? "allow" : "deny"));
    }
    return result;
}


//
// releaseLH
//
// Decrement the name's count in map.
// called with dataLock already taken
//
void ConnectionCounter::releaseLH(
    connectCountsMap_t& theMap, const std::string& theName) {

    connectCountsMap_t::iterator eRef = theMap.find(theName);
    if (eRef != theMap.end()) {
        uint16_t count = (uint16_t) (*eRef).second;
        assert (count > 0);
        if (1 == count) {
            theMap.erase (eRef);
        } else {
            (*eRef).second = count - 1;
        }
    } else {
        // User had no connections.
        // Connections denied by ACL never get users added
        //QPID_LOG(notice, "ACL ConnectionCounter Connection for '" << theName
        //    << "' not found in connection count pool");
    }
}


//
// connection - called during Connection's constructor
//
void ConnectionCounter::connection(broker::Connection& connection) {
    QPID_LOG(trace, "ACL ConnectionCounter new connection: " << connection.getMgmtId());

    const std::string& hostName(getClientHost(connection.getMgmtId()));

    Mutex::ScopedLock locker(dataLock);

    // Total connections goes up
    totalCurrentConnections += 1;

    // Record the fact that this connection exists
    connectProgressMap[connection.getMgmtId()] = C_CREATED;

    // Count the connection from this host.
    (void) countConnectionLH(connectByHostMap, hostName, hostLimit, false, false);
}


//
// closed - called during Connection's destructor
//
void ConnectionCounter::closed(broker::Connection& connection) {
    QPID_LOG(trace, "ACL ConnectionCounter closed: " << connection.getMgmtId()
        << ", userId:" << connection.getUserId());

    Mutex::ScopedLock locker(dataLock);

    connectCountsMap_t::iterator eRef = connectProgressMap.find(connection.getMgmtId());
    if (eRef != connectProgressMap.end()) {
        if ((*eRef).second == C_OPENED){
            // Normal case: connection was created and opened.
            // Decrement user in-use counts
            releaseLH(connectByNameMap,
                      connection.getUserId());
        } else {
            // Connection was created but not opened.
            // Don't decrement user count.
        }

        // Decrement host in-use count.
        releaseLH(connectByHostMap,
                  getClientHost(connection.getMgmtId()));

        // destroy connection progress indicator
        connectProgressMap.erase(eRef);

    } else {
        // connection not found in progress map
        QPID_LOG(notice, "ACL ConnectionCounter closed info for '" << connection.getMgmtId()
            << "' not found in connection state pool");
    }

    // total connections
    totalCurrentConnections -= 1;
}


//
// approveConnection
//  check total connections, connections from IP, connections by user and
//  disallow if over any limit
//
bool ConnectionCounter::approveConnection(
        const broker::Connection& connection,
        const std::string& userName,
        bool enforcingConnectionQuotas,
        uint16_t connectionUserQuota,
        boost::shared_ptr<AclData> localdata)
{
    const std::string& hostName(getClientHost(connection.getMgmtId()));

    Mutex::ScopedLock locker(dataLock);

    // Bump state from CREATED to OPENED
    (void) countConnectionLH(connectProgressMap, connection.getMgmtId(),
                             C_OPENED, false, false);

    // Run global deny/allow list check
    sys::SocketAddress sa(hostName, "");
    bool okByHostList(true);
    std::string hostLimitText;
    if (sa.isIp()) {
        AclResult result = localdata->isAllowedConnection(userName, hostName, hostLimitText);
        okByHostList = AclHelper::resultAllows(result);
        if (okByHostList) {
            QPID_LOG(trace, "ACL: ConnectionApprover host list " << hostLimitText);
        }
    }

    // Approve total connections
    bool okTotal  = true;
    if (totalLimit > 0) {
        okTotal = totalCurrentConnections <= totalLimit;
        QPID_LOG(trace, "ACL ConnectionApprover totalLimit=" << totalLimit
                 << " curValue=" << totalCurrentConnections
                 << " result=" << (okTotal ? "allow" : "deny"));
    }

    // Approve by IP host connections
    bool okByIP   = limitApproveLH(connectByHostMap, hostName, hostLimit, true);

    // Count and Approve the connection by the user
    bool okByUser = countConnectionLH(connectByNameMap, userName,
                                      connectionUserQuota, true,
                                      enforcingConnectionQuotas);

    // Emit separate log for each disapproval
    if (!okByHostList) {
        QPID_LOG(error, "ACL: ConnectionApprover host list " << hostLimitText
                 << " Connection refused.");
    }
    if (!okTotal) {
        QPID_LOG(error, "Client max total connection count limit of " << totalLimit
                 << " exceeded by '"
                 << connection.getMgmtId() << "', user: '"
                 << userName << "'. Connection refused");
    }
    if (!okByIP) {
        QPID_LOG(error, "Client max per-host connection count limit of "
                 << hostLimit << " exceeded by '"
                 << connection.getMgmtId() << "', user: '"
                 << userName << "'. Connection refused.");
    }
    if (!okByUser) {
        QPID_LOG(error, "Client max per-user connection count limit of "
                 << connectionUserQuota << " exceeded by '"
                 << connection.getMgmtId() << "', user: '"
                 << userName << "'. Connection refused.");
    }

    // Count/Event once for each disapproval
    bool result = okByHostList && okTotal && okByIP && okByUser;
    if (!result) {
        acl.reportConnectLimit(userName, hostName);
    }

    return result;
}

//
// getClientIp - given a connection's mgmtId return the client host part.
//
// TODO: Ideally this would be a method of the connection itself.
// TODO: Verify it works with rdma connection names.
//
std::string ConnectionCounter::getClientHost(const std::string mgmtId)
{
    size_t hyphen = mgmtId.find('-');
    if (std::string::npos != hyphen) {
        size_t colon = mgmtId.find_last_of(':');
        if (std::string::npos != colon) {
            // trailing colon found
            std::string tmp = mgmtId.substr(hyphen+1, colon - hyphen - 1);
            // undecorate ipv6
            if (tmp.length() >= 3 && tmp.find("[") == 0 && tmp.rfind("]") == tmp.length()-1)
                tmp = tmp.substr(1, tmp.length()-2);
            return tmp;

        } else {
            // colon not found - use everything after hyphen
            return mgmtId.substr(hyphen+1);
        }
    }

    // no hyphen found - use whole string
    return mgmtId;
}

}} // namespace qpid::ha
