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

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

    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;

    void dump(netdutils::DumpWriter& dw);
    void dumpIfaces(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);

    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
