/*
 * Copyright 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.
 *
 * TrafficControllerTest.cpp - unit tests for TrafficController.cpp
 */

#include <cstdint>
#include <string>
#include <vector>

#include <fcntl.h>
#include <inttypes.h>
#include <linux/inet_diag.h>
#include <linux/sock_diag.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#include <gtest/gtest.h>

#include <android-base/stringprintf.h>
#include <android-base/strings.h>

#include <netdutils/MockSyscalls.h>

#include "TrafficController.h"
#include "bpf/BpfUtils.h"

using namespace android::bpf;  // NOLINT(google-build-using-namespace): grandfathered

namespace android {
namespace net {

using base::Result;
using netdutils::isOk;

constexpr int TEST_MAP_SIZE = 10;
constexpr uid_t TEST_UID = 10086;
constexpr uid_t TEST_UID2 = 54321;
constexpr uid_t TEST_UID3 = 98765;
constexpr uint32_t TEST_TAG = 42;
constexpr uint32_t TEST_COUNTERSET = 1;
constexpr uint32_t DEFAULT_COUNTERSET = 0;

#define ASSERT_VALID(x) ASSERT_TRUE((x).isValid())

class TrafficControllerTest : public ::testing::Test {
  protected:
    TrafficControllerTest() {}
    TrafficController mTc;
    BpfMap<uint64_t, UidTagValue> mFakeCookieTagMap;
    BpfMap<uint32_t, uint8_t> mFakeUidCounterSetMap;
    BpfMap<uint32_t, StatsValue> mFakeAppUidStatsMap;
    BpfMap<StatsKey, StatsValue> mFakeStatsMapA;
    BpfMap<uint32_t, uint8_t> mFakeConfigurationMap;
    BpfMap<uint32_t, UidOwnerValue> mFakeUidOwnerMap;
    BpfMap<uint32_t, uint8_t> mFakeUidPermissionMap;

    void SetUp() {
        std::lock_guard guard(mTc.mMutex);
        ASSERT_EQ(0, setrlimitForTest());

        mFakeCookieTagMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint64_t), sizeof(UidTagValue),
                                          TEST_MAP_SIZE, 0));
        ASSERT_VALID(mFakeCookieTagMap);

        mFakeUidCounterSetMap.reset(
            createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
        ASSERT_VALID(mFakeUidCounterSetMap);

        mFakeAppUidStatsMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(StatsValue),
                                            TEST_MAP_SIZE, 0));
        ASSERT_VALID(mFakeAppUidStatsMap);

        mFakeStatsMapA.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(StatsKey), sizeof(StatsValue),
                                       TEST_MAP_SIZE, 0));
        ASSERT_VALID(mFakeStatsMapA);

        mFakeConfigurationMap.reset(
                createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), 1, 0));
        ASSERT_VALID(mFakeConfigurationMap);

        mFakeUidOwnerMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(UidOwnerValue),
                                         TEST_MAP_SIZE, 0));
        ASSERT_VALID(mFakeUidOwnerMap);
        mFakeUidPermissionMap.reset(
                createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
        ASSERT_VALID(mFakeUidPermissionMap);

        mTc.mCookieTagMap.reset(dupFd(mFakeCookieTagMap.getMap()));
        ASSERT_VALID(mTc.mCookieTagMap);
        mTc.mUidCounterSetMap.reset(dupFd(mFakeUidCounterSetMap.getMap()));
        ASSERT_VALID(mTc.mUidCounterSetMap);
        mTc.mAppUidStatsMap.reset(dupFd(mFakeAppUidStatsMap.getMap()));
        ASSERT_VALID(mTc.mAppUidStatsMap);
        mTc.mStatsMapA.reset(dupFd(mFakeStatsMapA.getMap()));
        ASSERT_VALID(mTc.mStatsMapA);
        mTc.mConfigurationMap.reset(dupFd(mFakeConfigurationMap.getMap()));
        ASSERT_VALID(mTc.mConfigurationMap);

        // Always write to stats map A by default.
        ASSERT_RESULT_OK(mTc.mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY,
                                                          SELECT_MAP_A, BPF_ANY));
        mTc.mUidOwnerMap.reset(dupFd(mFakeUidOwnerMap.getMap()));
        ASSERT_VALID(mTc.mUidOwnerMap);
        mTc.mUidPermissionMap.reset(dupFd(mFakeUidPermissionMap.getMap()));
        ASSERT_VALID(mTc.mUidPermissionMap);
        mTc.mPrivilegedUser.clear();
    }

    int dupFd(const android::base::unique_fd& mapFd) {
        return fcntl(mapFd.get(), F_DUPFD_CLOEXEC, 0);
    }

    void populateFakeStats(uint64_t cookie, uint32_t uid, uint32_t tag, StatsKey* key) {
        UidTagValue cookieMapkey = {.uid = (uint32_t)uid, .tag = tag};
        EXPECT_RESULT_OK(mFakeCookieTagMap.writeValue(cookie, cookieMapkey, BPF_ANY));
        *key = {.uid = uid, .tag = tag, .counterSet = TEST_COUNTERSET, .ifaceIndex = 1};
        StatsValue statsMapValue = {.rxPackets = 1, .rxBytes = 100};
        uint8_t counterSet = TEST_COUNTERSET;
        EXPECT_RESULT_OK(mFakeUidCounterSetMap.writeValue(uid, counterSet, BPF_ANY));
        EXPECT_RESULT_OK(mFakeStatsMapA.writeValue(*key, statsMapValue, BPF_ANY));
        key->tag = 0;
        EXPECT_RESULT_OK(mFakeStatsMapA.writeValue(*key, statsMapValue, BPF_ANY));
        EXPECT_RESULT_OK(mFakeAppUidStatsMap.writeValue(uid, statsMapValue, BPF_ANY));
        // put tag information back to statsKey
        key->tag = tag;
    }

    void checkUidOwnerRuleForChain(ChildChain chain, UidOwnerMatchType match) {
        uint32_t uid = TEST_UID;
        EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, DENYLIST));
        Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
        EXPECT_RESULT_OK(value);
        EXPECT_TRUE(value.value().rule & match);

        uid = TEST_UID2;
        EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, ALLOWLIST));
        value = mFakeUidOwnerMap.readValue(uid);
        EXPECT_RESULT_OK(value);
        EXPECT_TRUE(value.value().rule & match);

        EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, ALLOWLIST));
        value = mFakeUidOwnerMap.readValue(uid);
        EXPECT_FALSE(value.ok());
        EXPECT_EQ(ENOENT, value.error().code());

        uid = TEST_UID;
        EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, DENYLIST));
        value = mFakeUidOwnerMap.readValue(uid);
        EXPECT_FALSE(value.ok());
        EXPECT_EQ(ENOENT, value.error().code());

        uid = TEST_UID3;
        EXPECT_EQ(-ENOENT, mTc.changeUidOwnerRule(chain, uid, ALLOW, DENYLIST));
        value = mFakeUidOwnerMap.readValue(uid);
        EXPECT_FALSE(value.ok());
        EXPECT_EQ(ENOENT, value.error().code());
    }

    void checkEachUidValue(const std::vector<int32_t>& uids, UidOwnerMatchType match) {
        for (uint32_t uid : uids) {
            Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
            EXPECT_RESULT_OK(value);
            EXPECT_TRUE(value.value().rule & match);
        }
        std::set<uint32_t> uidSet(uids.begin(), uids.end());
        const auto checkNoOtherUid = [&uidSet](const int32_t& key,
                                               const BpfMap<uint32_t, UidOwnerValue>&) {
            EXPECT_NE(uidSet.end(), uidSet.find(key));
            return Result<void>();
        };
        EXPECT_RESULT_OK(mFakeUidOwnerMap.iterate(checkNoOtherUid));
    }

    void checkUidMapReplace(const std::string& name, const std::vector<int32_t>& uids,
                            UidOwnerMatchType match) {
        bool isAllowlist = true;
        EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isAllowlist, uids));
        checkEachUidValue(uids, match);

        isAllowlist = false;
        EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isAllowlist, uids));
        checkEachUidValue(uids, match);
    }

    void expectUidOwnerMapValues(const std::vector<uint32_t>& appUids, uint8_t expectedRule,
                                 uint32_t expectedIif) {
        for (uint32_t uid : appUids) {
            Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
            EXPECT_RESULT_OK(value);
            EXPECT_EQ(expectedRule, value.value().rule)
                    << "Expected rule for UID " << uid << " to be " << expectedRule << ", but was "
                    << value.value().rule;
            EXPECT_EQ(expectedIif, value.value().iif)
                    << "Expected iif for UID " << uid << " to be " << expectedIif << ", but was "
                    << value.value().iif;
        }
    }

    template <class Key, class Value>
    void expectMapEmpty(BpfMap<Key, Value>& map) {
        auto isEmpty = map.isEmpty();
        EXPECT_RESULT_OK(isEmpty);
        EXPECT_TRUE(isEmpty.value());
    }

    void expectUidPermissionMapValues(const std::vector<uid_t>& appUids, uint8_t expectedValue) {
        for (uid_t uid : appUids) {
            Result<uint8_t> value = mFakeUidPermissionMap.readValue(uid);
            EXPECT_RESULT_OK(value);
            EXPECT_EQ(expectedValue, value.value())
                    << "Expected value for UID " << uid << " to be " << expectedValue
                    << ", but was " << value.value();
        }
    }

    void expectPrivilegedUserSet(const std::vector<uid_t>& appUids) {
        std::lock_guard guard(mTc.mMutex);
        EXPECT_EQ(appUids.size(), mTc.mPrivilegedUser.size());
        for (uid_t uid : appUids) {
            EXPECT_NE(mTc.mPrivilegedUser.end(), mTc.mPrivilegedUser.find(uid));
        }
    }

    void expectPrivilegedUserSetEmpty() {
        std::lock_guard guard(mTc.mMutex);
        EXPECT_TRUE(mTc.mPrivilegedUser.empty());
    }

    void addPrivilegedUid(uid_t uid) {
        std::vector privilegedUid = {uid};
        mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, privilegedUid);
    }

    void removePrivilegedUid(uid_t uid) {
        std::vector privilegedUid = {uid};
        mTc.setPermissionForUids(INetd::PERMISSION_NONE, privilegedUid);
    }

    void expectFakeStatsUnchanged(uint64_t cookie, uint32_t tag, uint32_t uid,
                                  StatsKey tagStatsMapKey) {
        Result<UidTagValue> cookieMapResult = mFakeCookieTagMap.readValue(cookie);
        EXPECT_RESULT_OK(cookieMapResult);
        EXPECT_EQ(uid, cookieMapResult.value().uid);
        EXPECT_EQ(tag, cookieMapResult.value().tag);
        Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
        EXPECT_RESULT_OK(counterSetResult);
        EXPECT_EQ(TEST_COUNTERSET, counterSetResult.value());
        Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
        EXPECT_RESULT_OK(statsMapResult);
        EXPECT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
        EXPECT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
        tagStatsMapKey.tag = 0;
        statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
        EXPECT_RESULT_OK(statsMapResult);
        EXPECT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
        EXPECT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
        auto appStatsResult = mFakeAppUidStatsMap.readValue(uid);
        EXPECT_RESULT_OK(appStatsResult);
        EXPECT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
        EXPECT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
    }
};

TEST_F(TrafficControllerTest, TestSetCounterSet) {
    uid_t callingUid = TEST_UID2;
    addPrivilegedUid(callingUid);
    ASSERT_EQ(0, mTc.setCounterSet(TEST_COUNTERSET, TEST_UID, callingUid));
    uid_t uid = TEST_UID;
    Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
    ASSERT_RESULT_OK(counterSetResult);
    ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
    ASSERT_EQ(0, mTc.setCounterSet(DEFAULT_COUNTERSET, TEST_UID, callingUid));
    ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
    expectMapEmpty(mFakeUidCounterSetMap);
}

TEST_F(TrafficControllerTest, TestSetCounterSetWithoutPermission) {
    ASSERT_EQ(-EPERM, mTc.setCounterSet(TEST_COUNTERSET, TEST_UID, TEST_UID2));
    uid_t uid = TEST_UID;
    ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
    expectMapEmpty(mFakeUidCounterSetMap);
}

TEST_F(TrafficControllerTest, TestSetInvalidCounterSet) {
    uid_t callingUid = TEST_UID2;
    addPrivilegedUid(callingUid);
    ASSERT_GT(0, mTc.setCounterSet(OVERFLOW_COUNTERSET, TEST_UID, callingUid));
    uid_t uid = TEST_UID;
    ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
    expectMapEmpty(mFakeUidCounterSetMap);
}

TEST_F(TrafficControllerTest, TestDeleteTagDataWithoutPermission) {
    uint64_t cookie = 1;
    uid_t uid = TEST_UID;
    uint32_t tag = TEST_TAG;
    StatsKey tagStatsMapKey;
    populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
    ASSERT_EQ(-EPERM, mTc.deleteTagData(0, TEST_UID, TEST_UID2));

    expectFakeStatsUnchanged(cookie, tag, uid, tagStatsMapKey);
}

TEST_F(TrafficControllerTest, TestDeleteTagData) {
    uid_t callingUid = TEST_UID2;
    addPrivilegedUid(callingUid);
    uint64_t cookie = 1;
    uid_t uid = TEST_UID;
    uint32_t tag = TEST_TAG;
    StatsKey tagStatsMapKey;
    populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
    ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID, callingUid));
    ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie).ok());
    Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
    ASSERT_RESULT_OK(counterSetResult);
    ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey).ok());
    tagStatsMapKey.tag = 0;
    Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
    ASSERT_RESULT_OK(statsMapResult);
    ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
    ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
    auto appStatsResult = mFakeAppUidStatsMap.readValue(TEST_UID);
    ASSERT_RESULT_OK(appStatsResult);
    ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
    ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
}

TEST_F(TrafficControllerTest, TestDeleteAllUidData) {
    uid_t callingUid = TEST_UID2;
    addPrivilegedUid(callingUid);
    uint64_t cookie = 1;
    uid_t uid = TEST_UID;
    uint32_t tag = TEST_TAG;
    StatsKey tagStatsMapKey;
    populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
    ASSERT_EQ(0, mTc.deleteTagData(0, TEST_UID, callingUid));
    ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie).ok());
    ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey).ok());
    tagStatsMapKey.tag = 0;
    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey).ok());
    ASSERT_FALSE(mFakeAppUidStatsMap.readValue(TEST_UID).ok());
}

TEST_F(TrafficControllerTest, TestDeleteDataWithTwoTags) {
    uid_t callingUid = TEST_UID2;
    addPrivilegedUid(callingUid);
    uint64_t cookie1 = 1;
    uint64_t cookie2 = 2;
    uid_t uid = TEST_UID;
    uint32_t tag1 = TEST_TAG;
    uint32_t tag2 = TEST_TAG + 1;
    StatsKey tagStatsMapKey1;
    StatsKey tagStatsMapKey2;
    populateFakeStats(cookie1, uid, tag1, &tagStatsMapKey1);
    populateFakeStats(cookie2, uid, tag2, &tagStatsMapKey2);
    ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID, callingUid));
    ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie1).ok());
    Result<UidTagValue> cookieMapResult = mFakeCookieTagMap.readValue(cookie2);
    ASSERT_RESULT_OK(cookieMapResult);
    ASSERT_EQ(TEST_UID, cookieMapResult.value().uid);
    ASSERT_EQ(TEST_TAG + 1, cookieMapResult.value().tag);
    Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
    ASSERT_RESULT_OK(counterSetResult);
    ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey1).ok());
    Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey2);
    ASSERT_RESULT_OK(statsMapResult);
    ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
    ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
}

TEST_F(TrafficControllerTest, TestDeleteDataWithTwoUids) {
    uid_t callingUid = TEST_UID2;
    addPrivilegedUid(callingUid);
    uint64_t cookie1 = 1;
    uint64_t cookie2 = 2;
    uid_t uid1 = TEST_UID;
    uid_t uid2 = TEST_UID + 1;
    uint32_t tag = TEST_TAG;
    StatsKey tagStatsMapKey1;
    StatsKey tagStatsMapKey2;
    populateFakeStats(cookie1, uid1, tag, &tagStatsMapKey1);
    populateFakeStats(cookie2, uid2, tag, &tagStatsMapKey2);

    // Delete the stats of one of the uid. Check if it is properly collected by
    // removedStats.
    ASSERT_EQ(0, mTc.deleteTagData(0, uid2, callingUid));
    ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie2).ok());
    Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid1);
    ASSERT_RESULT_OK(counterSetResult);
    ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
    ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid2).ok());
    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey2).ok());
    tagStatsMapKey2.tag = 0;
    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey2).ok());
    ASSERT_FALSE(mFakeAppUidStatsMap.readValue(uid2).ok());
    tagStatsMapKey1.tag = 0;
    Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey1);
    ASSERT_RESULT_OK(statsMapResult);
    ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
    ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
    auto appStatsResult = mFakeAppUidStatsMap.readValue(uid1);
    ASSERT_RESULT_OK(appStatsResult);
    ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
    ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);

    // Delete the stats of the other uid.
    ASSERT_EQ(0, mTc.deleteTagData(0, uid1, callingUid));
    ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey1).ok());
    ASSERT_FALSE(mFakeAppUidStatsMap.readValue(uid1).ok());
}

TEST_F(TrafficControllerTest, TestUpdateOwnerMapEntry) {
    uint32_t uid = TEST_UID;
    ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, DENY, DENYLIST)));
    Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
    ASSERT_RESULT_OK(value);
    ASSERT_TRUE(value.value().rule & STANDBY_MATCH);

    ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, ALLOW, ALLOWLIST)));
    value = mFakeUidOwnerMap.readValue(uid);
    ASSERT_RESULT_OK(value);
    ASSERT_TRUE(value.value().rule & DOZABLE_MATCH);

    ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, DENY, ALLOWLIST)));
    value = mFakeUidOwnerMap.readValue(uid);
    ASSERT_RESULT_OK(value);
    ASSERT_FALSE(value.value().rule & DOZABLE_MATCH);

    ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, DENYLIST)));
    ASSERT_FALSE(mFakeUidOwnerMap.readValue(uid).ok());

    uid = TEST_UID2;
    ASSERT_FALSE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, DENYLIST)));
    ASSERT_FALSE(mFakeUidOwnerMap.readValue(uid).ok());
}

TEST_F(TrafficControllerTest, TestChangeUidOwnerRule) {
    checkUidOwnerRuleForChain(DOZABLE, DOZABLE_MATCH);
    checkUidOwnerRuleForChain(STANDBY, STANDBY_MATCH);
    checkUidOwnerRuleForChain(POWERSAVE, POWERSAVE_MATCH);
    checkUidOwnerRuleForChain(RESTRICTED, RESTRICTED_MATCH);
    ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(NONE, TEST_UID, ALLOW, ALLOWLIST));
    ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(INVALID_CHAIN, TEST_UID, ALLOW, ALLOWLIST));
}

TEST_F(TrafficControllerTest, TestReplaceUidOwnerMap) {
    std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
    checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
    checkUidMapReplace("fw_standby", uids, STANDBY_MATCH);
    checkUidMapReplace("fw_powersave", uids, POWERSAVE_MATCH);
    checkUidMapReplace("fw_restricted", uids, RESTRICTED_MATCH);
    ASSERT_EQ(-EINVAL, mTc.replaceUidOwnerMap("unknow", true, uids));
}

TEST_F(TrafficControllerTest, TestReplaceSameChain) {
    std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
    checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
    std::vector<int32_t> newUids = {TEST_UID2, TEST_UID3};
    checkUidMapReplace("fw_dozable", newUids, DOZABLE_MATCH);
}

TEST_F(TrafficControllerTest, TestDenylistUidMatch) {
    std::vector<uint32_t> appUids = {1000, 1001, 10012};
    ASSERT_TRUE(isOk(
            mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH, TrafficController::IptOpInsert)));
    expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);
    ASSERT_TRUE(isOk(
            mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH, TrafficController::IptOpDelete)));
    expectMapEmpty(mFakeUidOwnerMap);
}

TEST_F(TrafficControllerTest, TestAllowlistUidMatch) {
    std::vector<uint32_t> appUids = {1000, 1001, 10012};
    ASSERT_TRUE(
            isOk(mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpInsert)));
    expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
    ASSERT_TRUE(
            isOk(mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpDelete)));
    expectMapEmpty(mFakeUidOwnerMap);
}

TEST_F(TrafficControllerTest, TestReplaceMatchUid) {
    std::vector<uint32_t> appUids = {1000, 1001, 10012};
    // Add appUids to the denylist and expect that their values are all PENALTY_BOX_MATCH.
    ASSERT_TRUE(isOk(
            mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH, TrafficController::IptOpInsert)));
    expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);

    // Add the same UIDs to the allowlist and expect that we get PENALTY_BOX_MATCH |
    // HAPPY_BOX_MATCH.
    ASSERT_TRUE(
            isOk(mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpInsert)));
    expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH | PENALTY_BOX_MATCH, 0);

    // Remove the same UIDs from the allowlist and check the PENALTY_BOX_MATCH is still there.
    ASSERT_TRUE(
            isOk(mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpDelete)));
    expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);

    // Remove the same UIDs from the denylist and check the map is empty.
    ASSERT_TRUE(isOk(
            mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH, TrafficController::IptOpDelete)));
    ASSERT_FALSE(mFakeUidOwnerMap.getFirstKey().ok());
}

TEST_F(TrafficControllerTest, TestDeleteWrongMatchSilentlyFails) {
    std::vector<uint32_t> appUids = {1000, 1001, 10012};
    // If the uid does not exist in the map, trying to delete a rule about it will fail.
    ASSERT_FALSE(
            isOk(mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpDelete)));
    expectMapEmpty(mFakeUidOwnerMap);

    // Add denylist rules for appUids.
    ASSERT_TRUE(
            isOk(mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, TrafficController::IptOpInsert)));
    expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);

    // Delete (non-existent) denylist rules for appUids, and check that this silently does
    // nothing if the uid is in the map but does not have denylist match. This is required because
    // NetworkManagementService will try to remove a uid from denylist after adding it to the
    // allowlist and if the remove fails it will not update the uid status.
    ASSERT_TRUE(isOk(
            mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH, TrafficController::IptOpDelete)));
    expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
}

TEST_F(TrafficControllerTest, TestAddUidInterfaceFilteringRules) {
    int iif0 = 15;
    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif0, {1000, 1001})));
    expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);

    // Add some non-overlapping new uids. They should coexist with existing rules
    int iif1 = 16;
    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {2000, 2001})));
    expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
    expectUidOwnerMapValues({2000, 2001}, IIF_MATCH, iif1);

    // Overwrite some existing uids
    int iif2 = 17;
    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif2, {1000, 2000})));
    expectUidOwnerMapValues({1001}, IIF_MATCH, iif0);
    expectUidOwnerMapValues({2001}, IIF_MATCH, iif1);
    expectUidOwnerMapValues({1000, 2000}, IIF_MATCH, iif2);
}

TEST_F(TrafficControllerTest, TestRemoveUidInterfaceFilteringRules) {
    int iif0 = 15;
    int iif1 = 16;
    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif0, {1000, 1001})));
    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {2000, 2001})));
    expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
    expectUidOwnerMapValues({2000, 2001}, IIF_MATCH, iif1);

    // Rmove some uids
    ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1001, 2001})));
    expectUidOwnerMapValues({1000}, IIF_MATCH, iif0);
    expectUidOwnerMapValues({2000}, IIF_MATCH, iif1);
    checkEachUidValue({1000, 2000}, IIF_MATCH);  // Make sure there are only two uids remaining

    // Remove non-existent uids shouldn't fail
    ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({2000, 3000})));
    expectUidOwnerMapValues({1000}, IIF_MATCH, iif0);
    checkEachUidValue({1000}, IIF_MATCH);  // Make sure there are only one uid remaining

    // Remove everything
    ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1000})));
    expectMapEmpty(mFakeUidOwnerMap);
}

TEST_F(TrafficControllerTest, TestUidInterfaceFilteringRulesCoexistWithExistingMatches) {
    // Set up existing PENALTY_BOX_MATCH rules
    ASSERT_TRUE(isOk(mTc.updateUidOwnerMap({1000, 1001, 10012}, PENALTY_BOX_MATCH,
                                           TrafficController::IptOpInsert)));
    expectUidOwnerMapValues({1000, 1001, 10012}, PENALTY_BOX_MATCH, 0);

    // Add some partially-overlapping uid owner rules and check result
    int iif1 = 32;
    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {10012, 10013, 10014})));
    expectUidOwnerMapValues({1000, 1001}, PENALTY_BOX_MATCH, 0);
    expectUidOwnerMapValues({10012}, PENALTY_BOX_MATCH | IIF_MATCH, iif1);
    expectUidOwnerMapValues({10013, 10014}, IIF_MATCH, iif1);

    // Removing some PENALTY_BOX_MATCH rules should not change uid interface rule
    ASSERT_TRUE(isOk(mTc.updateUidOwnerMap({1001, 10012}, PENALTY_BOX_MATCH,
                                           TrafficController::IptOpDelete)));
    expectUidOwnerMapValues({1000}, PENALTY_BOX_MATCH, 0);
    expectUidOwnerMapValues({10012, 10013, 10014}, IIF_MATCH, iif1);

    // Remove all uid interface rules
    ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({10012, 10013, 10014})));
    expectUidOwnerMapValues({1000}, PENALTY_BOX_MATCH, 0);
    // Make sure these are the only uids left
    checkEachUidValue({1000}, PENALTY_BOX_MATCH);
}

TEST_F(TrafficControllerTest, TestUidInterfaceFilteringRulesCoexistWithNewMatches) {
    int iif1 = 56;
    // Set up existing uid interface rules
    ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {10001, 10002})));
    expectUidOwnerMapValues({10001, 10002}, IIF_MATCH, iif1);

    // Add some partially-overlapping doze rules
    EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_dozable", true, {10002, 10003}));
    expectUidOwnerMapValues({10001}, IIF_MATCH, iif1);
    expectUidOwnerMapValues({10002}, DOZABLE_MATCH | IIF_MATCH, iif1);
    expectUidOwnerMapValues({10003}, DOZABLE_MATCH, 0);

    // Introduce a third rule type (powersave) on various existing UIDs
    EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_powersave", true, {10000, 10001, 10002, 10003}));
    expectUidOwnerMapValues({10000}, POWERSAVE_MATCH, 0);
    expectUidOwnerMapValues({10001}, POWERSAVE_MATCH | IIF_MATCH, iif1);
    expectUidOwnerMapValues({10002}, POWERSAVE_MATCH | DOZABLE_MATCH | IIF_MATCH, iif1);
    expectUidOwnerMapValues({10003}, POWERSAVE_MATCH | DOZABLE_MATCH, 0);

    // Remove all doze rules
    EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_dozable", true, {}));
    expectUidOwnerMapValues({10000}, POWERSAVE_MATCH, 0);
    expectUidOwnerMapValues({10001}, POWERSAVE_MATCH | IIF_MATCH, iif1);
    expectUidOwnerMapValues({10002}, POWERSAVE_MATCH | IIF_MATCH, iif1);
    expectUidOwnerMapValues({10003}, POWERSAVE_MATCH, 0);

    // Remove all powersave rules, expect ownerMap to only have uid interface rules left
    EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_powersave", true, {}));
    expectUidOwnerMapValues({10001, 10002}, IIF_MATCH, iif1);
    // Make sure these are the only uids left
    checkEachUidValue({10001, 10002}, IIF_MATCH);
}

TEST_F(TrafficControllerTest, TestGrantInternetPermission) {
    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};

    mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, appUids);
    expectMapEmpty(mFakeUidPermissionMap);
    expectPrivilegedUserSetEmpty();
}

TEST_F(TrafficControllerTest, TestRevokeInternetPermission) {
    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};

    mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
    expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
}

TEST_F(TrafficControllerTest, TestPermissionUninstalled) {
    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};

    mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
    expectUidPermissionMapValues(appUids, INetd::PERMISSION_UPDATE_DEVICE_STATS);
    expectPrivilegedUserSet(appUids);

    std::vector<uid_t> uidToRemove = {TEST_UID};
    mTc.setPermissionForUids(INetd::PERMISSION_UNINSTALLED, uidToRemove);

    std::vector<uid_t> uidRemain = {TEST_UID3, TEST_UID2};
    expectUidPermissionMapValues(uidRemain, INetd::PERMISSION_UPDATE_DEVICE_STATS);
    expectPrivilegedUserSet(uidRemain);

    mTc.setPermissionForUids(INetd::PERMISSION_UNINSTALLED, uidRemain);
    expectMapEmpty(mFakeUidPermissionMap);
    expectPrivilegedUserSetEmpty();
}

TEST_F(TrafficControllerTest, TestGrantUpdateStatsPermission) {
    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};

    mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
    expectUidPermissionMapValues(appUids, INetd::PERMISSION_UPDATE_DEVICE_STATS);
    expectPrivilegedUserSet(appUids);

    mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
    expectPrivilegedUserSetEmpty();
    expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
}

TEST_F(TrafficControllerTest, TestRevokeUpdateStatsPermission) {
    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};

    mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
    expectPrivilegedUserSet(appUids);

    std::vector<uid_t> uidToRemove = {TEST_UID};
    mTc.setPermissionForUids(INetd::PERMISSION_NONE, uidToRemove);

    std::vector<uid_t> uidRemain = {TEST_UID3, TEST_UID2};
    expectPrivilegedUserSet(uidRemain);

    mTc.setPermissionForUids(INetd::PERMISSION_NONE, uidRemain);
    expectPrivilegedUserSetEmpty();
}

TEST_F(TrafficControllerTest, TestGrantWrongPermission) {
    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};

    mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
    expectPrivilegedUserSetEmpty();
    expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
}

TEST_F(TrafficControllerTest, TestGrantDuplicatePermissionSlientlyFail) {
    std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};

    mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, appUids);
    expectMapEmpty(mFakeUidPermissionMap);

    std::vector<uid_t> uidToAdd = {TEST_UID};
    mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, uidToAdd);

    expectPrivilegedUserSetEmpty();

    mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
    expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);

    mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
    expectPrivilegedUserSet(appUids);

    mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, uidToAdd);
    expectPrivilegedUserSet(appUids);

    mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
    expectPrivilegedUserSetEmpty();
}

}  // namespace net
}  // namespace android
