/*
 * 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/StatusOr.h>
#include <sysutils/SocketClient.h>

#include "NetdConstants.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;

    // 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{};

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

    bool enableForwarding(const char* requester);
    bool disableForwarding(const char* requester);
    size_t forwardingRequestCount();

    int startTethering(int num_addrs, char **dhcp_ranges);
    int startTethering(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();

    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;
        }
    };

    typedef std::vector<TetherStats> TetherStatsList;

    netdutils::StatusOr<TetherStatsList> getTetherStats();

    /*
     * 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;

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);

    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
