/*
 * Copyright (C) 2008 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 _TETHER_CONTROLLER_H
#define _TETHER_CONTROLLER_H

#include <list>
#include <set>
#include <string>

#include <netdutils/DumpWriter.h>
#include <netdutils/StatusOr.h>
#include <sysutils/SocketClient.h>

#include "NetdConstants.h"
#include "android-base/result.h"
#include "bpf/BpfMap.h"
#include "netdbpf/bpf_shared.h"

#include "android/net/TetherOffloadRuleParcel.h"

namespace android {
namespace net {

class TetherController {
  private:
    struct ForwardingDownstream {
        std::string iface;
        bool active;
    };

    std::list<std::string> mInterfaces;

    // Map upstream iface -> downstream iface. A pair is in the map if forwarding was enabled at
    // some point since the controller was initialized.
    std::multimap<std::string, ForwardingDownstream> mFwdIfaces;

    bool mIsTetheringStarted = false;

    // NetId to use for forwarded DNS queries. This may not be the default
    // network, e.g., in the case where we are tethering to a DUN APN.
    unsigned               mDnsNetId = 0;
    std::list<std::string> mDnsForwarders;
    pid_t                  mDaemonPid = 0;
    int                    mDaemonFd = -1;
    std::set<std::string>  mForwardingRequests;

    struct DnsmasqState {
        static int sendCmd(int daemonFd, const std::string& cmd);

        // List of downstream interfaces on which to serve. The format used is:
        //     update_ifaces|<ifname1>|<ifname2>|...
        std::string update_ifaces_cmd;
        // Forwarding (upstream) DNS configuration to use. The format used is:
        //     update_dns|<hex_socket_mark>|<ip1>|<ip2>|...
        std::string update_dns_cmd;

        void clear();
        int sendAllState(int daemonFd) const;
    } mDnsmasqState{};

    // BPF maps, initialized by initMaps.
    bpf::BpfMap<TetherDownstream6Key, TetherDownstream6Value> mBpfDownstream6Map;
    bpf::BpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap;
    bpf::BpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap;

  public:
    TetherController();
    ~TetherController() = default;

    bool enableForwarding(const char* requester);
    bool disableForwarding(const char* requester);
    const std::set<std::string>& getIpfwdRequesterList() const;

    //TODO: Clean up the overload function
    int startTethering(bool isLegacyDnsProxy, int num_addrs, char** dhcp_ranges);
    int startTethering(bool isLegacyDnsProxy, const std::vector<std::string>& dhcpRanges);
    int stopTethering();
    bool isTetheringStarted();

    unsigned getDnsNetId();
    int setDnsForwarders(unsigned netId, char **servers, int numServers);
    int setDnsForwarders(unsigned netId, const std::vector<std::string>& servers);
    const std::list<std::string> &getDnsForwarders() const;

    int tetherInterface(const char *interface);
    int untetherInterface(const char *interface);
    const std::list<std::string> &getTetheredInterfaceList() const;
    bool applyDnsInterfaces();

    int enableNat(const char* intIface, const char* extIface);
    int disableNat(const char* intIface, const char* extIface);
    int setupIptablesHooks();

    base::Result<void> addOffloadRule(const TetherOffloadRuleParcel& rule);
    base::Result<void> removeOffloadRule(const TetherOffloadRuleParcel& rule);

    int setTetherOffloadInterfaceQuota(int ifIndex, int64_t maxBytes);

    class TetherStats {
      public:
        TetherStats() = default;
        TetherStats(std::string intIfn, std::string extIfn,
                int64_t rxB, int64_t rxP,
                int64_t txB, int64_t txP)
                        : intIface(intIfn), extIface(extIfn),
                            rxBytes(rxB), rxPackets(rxP),
                            txBytes(txB), txPackets(txP) {};
        std::string intIface;
        std::string extIface;
        int64_t rxBytes = -1;
        int64_t rxPackets = -1;
        int64_t txBytes = -1;
        int64_t txPackets = -1;

        bool addStatsIfMatch(const TetherStats& other) {
            if (intIface == other.intIface && extIface == other.extIface) {
                rxBytes   += other.rxBytes;
                rxPackets += other.rxPackets;
                txBytes   += other.txBytes;
                txPackets += other.txPackets;
                return true;
            }
            return false;
        }
    };

    struct TetherOffloadStats {
        int ifIndex;
        int64_t rxBytes;
        int64_t rxPackets;
        int64_t txBytes;
        int64_t txPackets;
    };

    typedef std::vector<TetherStats> TetherStatsList;
    typedef std::vector<TetherOffloadStats> TetherOffloadStatsList;

    netdutils::StatusOr<TetherStatsList> getTetherStats();
    netdutils::StatusOr<TetherOffloadStatsList> getTetherOffloadStats();
    base::Result<TetherOffloadStats> getAndClearTetherOffloadStats(int ifIndex);

    /*
     * extraProcessingInfo: contains raw parsed data, and error info.
     * This strongly requires that setup of the rules is in a specific order:
     *  in:intIface out:extIface
     *  in:extIface out:intIface
     * and the rules are grouped in pairs when more that one tethering was setup.
     */
    static int addForwardChainStats(TetherStatsList& statsList, const std::string& iptOutput,
                                    std::string &extraProcessingInfo);

    static constexpr const char* LOCAL_FORWARD               = "tetherctrl_FORWARD";
    static constexpr const char* LOCAL_MANGLE_FORWARD        = "tetherctrl_mangle_FORWARD";
    static constexpr const char* LOCAL_NAT_POSTROUTING       = "tetherctrl_nat_POSTROUTING";
    static constexpr const char* LOCAL_RAW_PREROUTING        = "tetherctrl_raw_PREROUTING";
    static constexpr const char* LOCAL_TETHER_COUNTERS_CHAIN = "tetherctrl_counters";

    std::mutex lock;

    void dump(netdutils::DumpWriter& dw);
    void dumpIfaces(netdutils::DumpWriter& dw);
    void dumpBpf(netdutils::DumpWriter& dw);

  private:
    bool setIpFwdEnabled();
    std::vector<char*> toCstrVec(const std::vector<std::string>& addrs);
    int setupIPv6CountersChain();
    static std::string makeTetherCountingRule(const char *if1, const char *if2);
    ForwardingDownstream* findForwardingDownstream(const std::string& intIface,
        const std::string& extIface);
    void addForwardingPair(const std::string& intIface, const std::string& extIface);
    void markForwardingPairDisabled(const std::string& intIface, const std::string& extIface);

    bool isForwardingPairEnabled(const std::string& intIface, const std::string& extIface);
    bool isAnyForwardingEnabledOnUpstream(const std::string& extIface);
    bool isAnyForwardingPairEnabled();
    bool tetherCountingRuleExists(const std::string& iface1, const std::string& iface2);

    int setDefaults();
    int setTetherGlobalAlertRule();
    int setForwardRules(bool set, const char *intIface, const char *extIface);
    int setTetherCountingRules(bool add, const char *intIface, const char *extIface);

    base::Result<void> setBpfLimit(uint32_t ifIndex, uint64_t limit);
    void initMaps();
    void startBpf(const char* iface, bool downstream);
    void stopBpf(const char* iface);

    static void addStats(TetherStatsList& statsList, const TetherStats& stats);

    // For testing.
    friend class TetherControllerTest;
    static int (*iptablesRestoreFunction)(IptablesTarget, const std::string&, std::string *);
};

}  // namespace net
}  // namespace android

#endif
