/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed 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.
 */

#ifndef NFLOG_LISTENER_H
#define NFLOG_LISTENER_H

#include <netdutils/Netfilter.h>

#include "netdutils/NetlinkListener.h"
#include "netdutils/StatusOr.h"

namespace android {
namespace net {

class NFLogListenerInterface {
  public:
    using DispatchFn =
        std::function<void(const nlmsghdr& nlmsg, const nfgenmsg& nfmsg,
                           const netdutils::Slice msg)>;

    virtual ~NFLogListenerInterface() = default;

    // Similar to NetlinkListener::subscribe() but performs an additional
    // level of deserialization and dispatch.
    //
    // Threadsafe.
    // All dispatch functions invoked on a single service thread.
    // subscribe() and join() must not be called from the stack of fn().
    virtual netdutils::Status subscribe(uint16_t nfLogGroup, const DispatchFn& fn) = 0;

    // Overloaded version of subscribe which allows to specify a copyRange for obtaining packet
    // payloads.
    virtual netdutils::Status subscribe(
            uint16_t nfLogGroup, uint32_t copyRange, const DispatchFn& fn) = 0;

    // Halt delivery of messages from a nfLogGroup previously subscribed to above.
    //
    // Threadsafe.
    virtual netdutils::Status unsubscribe(uint16_t nfLogGroup) = 0;
};

// NFLogListener manages a single netlink socket with specialized
// settings required for processing of NFLOG messages.
//
// NFLogListener currently assumes that it is ok to drop messages
// generated by the kernel when under heavy load. This makes the
// class most suitable for advisory tasks and statistics.
class NFLogListener : public NFLogListenerInterface {
  public:
    using DispatchFn = NFLogListenerInterface::DispatchFn;

    // Do not invoke this constructor directly outside of tests. Use
    // makeNFLogListener() instead.
    NFLogListener(std::shared_ptr<netdutils::NetlinkListenerInterface> listener);

    ~NFLogListener() override;

    netdutils::Status subscribe(uint16_t nfLogGroup, const DispatchFn& fn) override;

    netdutils::Status subscribe(
            uint16_t nfLogGroup, uint32_t copyRange, const DispatchFn& fn) override;

    netdutils::Status unsubscribe(uint16_t nfLogGroup) override;

  private:
    std::shared_ptr<netdutils::NetlinkListenerInterface> mListener;
    std::mutex mMutex;
    std::map<uint16_t, DispatchFn> mDispatchMap;  // guarded by mMutex
};

// Allocate and return a new NFLogListener. On success, the returned
// listener is ready to use with a running service thread.
netdutils::StatusOr<std::unique_ptr<NFLogListener>> makeNFLogListener();

}  // namespace net
}  // namespace android

#endif /* NFLOG_LISTENER_H */
