/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, versionCode 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.
 */
#define DEBUG false  // STOPSHIP if true
#include "Log.h"

#include "stats_log_util.h"
#include "guardrail/StatsdStats.h"
#include "packages/UidMap.h"

#include <android/os/IStatsCompanionService.h>
#include <binder/IServiceManager.h>
#include <utils/Errors.h>

#include <inttypes.h>

using namespace android;

using android::base::StringPrintf;
using android::util::FIELD_COUNT_REPEATED;
using android::util::FIELD_TYPE_BOOL;
using android::util::FIELD_TYPE_FLOAT;
using android::util::FIELD_TYPE_INT32;
using android::util::FIELD_TYPE_INT64;
using android::util::FIELD_TYPE_MESSAGE;
using android::util::FIELD_TYPE_STRING;
using android::util::ProtoOutputStream;

namespace android {
namespace os {
namespace statsd {

const int FIELD_ID_SNAPSHOT_PACKAGE_NAME = 1;
const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION = 2;
const int FIELD_ID_SNAPSHOT_PACKAGE_UID = 3;
const int FIELD_ID_SNAPSHOT_TIMESTAMP = 1;
const int FIELD_ID_SNAPSHOT_PACKAGE_INFO = 2;
const int FIELD_ID_SNAPSHOTS = 1;
const int FIELD_ID_CHANGES = 2;
const int FIELD_ID_CHANGE_DELETION = 1;
const int FIELD_ID_CHANGE_TIMESTAMP = 2;
const int FIELD_ID_CHANGE_PACKAGE = 3;
const int FIELD_ID_CHANGE_UID = 4;
const int FIELD_ID_CHANGE_VERSION = 5;

UidMap::UidMap() : mBytesUsed(0) {}

UidMap::~UidMap() {}

bool UidMap::hasApp(int uid, const string& packageName) const {
    lock_guard<mutex> lock(mMutex);

    auto range = mMap.equal_range(uid);
    for (auto it = range.first; it != range.second; ++it) {
        if (it->second.packageName == packageName) {
            return true;
        }
    }
    return false;
}

string UidMap::normalizeAppName(const string& appName) const {
    string normalizedName = appName;
    std::transform(normalizedName.begin(), normalizedName.end(), normalizedName.begin(), ::tolower);
    return normalizedName;
}

std::set<string> UidMap::getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const {
    lock_guard<mutex> lock(mMutex);
    return getAppNamesFromUidLocked(uid,returnNormalized);
}

std::set<string> UidMap::getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const {
    std::set<string> names;
    auto range = mMap.equal_range(uid);
    for (auto it = range.first; it != range.second; ++it) {
        names.insert(returnNormalized ?
            normalizeAppName(it->second.packageName) : it->second.packageName);
    }
    return names;
}

int64_t UidMap::getAppVersion(int uid, const string& packageName) const {
    lock_guard<mutex> lock(mMutex);

    auto range = mMap.equal_range(uid);
    for (auto it = range.first; it != range.second; ++it) {
        if (it->second.packageName == packageName) {
            return it->second.versionCode;
        }
    }
    return 0;
}

void UidMap::updateMap(const vector<int32_t>& uid, const vector<int64_t>& versionCode,
                       const vector<String16>& packageName) {
    updateMap(getElapsedRealtimeNs(), uid, versionCode, packageName);
}

void UidMap::updateMap(const int64_t& timestamp, const vector<int32_t>& uid,
                       const vector<int64_t>& versionCode, const vector<String16>& packageName) {
    vector<wp<PackageInfoListener>> broadcastList;
    {
        lock_guard<mutex> lock(mMutex);  // Exclusively lock for updates.

        mMap.clear();
        vector<const SnapshotPackageInfo> infos;
        for (size_t j = 0; j < uid.size(); j++) {
            string package = string(String8(packageName[j]).string());
            mMap.insert(make_pair(uid[j], AppData(package, versionCode[j])));
            infos.emplace_back(package, versionCode[j], uid[j]);
        }

        mSnapshots.emplace_back(timestamp, infos);

        mBytesUsed += mSnapshots.back().bytes;
        ensureBytesUsedBelowLimit();
        StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
        StatsdStats::getInstance().setUidMapSnapshots(mSnapshots.size());
        getListenerListCopyLocked(&broadcastList);
    }
    // To avoid invoking callback while holding the internal lock. we get a copy of the listener
    // list and invoke the callback. It's still possible that after we copy the list, a
    // listener removes itself before we call it. It's then the listener's job to handle it (expect
    // the callback to be called after listener is removed, and the listener should properly
    // ignore it).
    for (auto weakPtr : broadcastList) {
        auto strongPtr = weakPtr.promote();
        if (strongPtr != NULL) {
            strongPtr->onUidMapReceived(timestamp);
        }
    }
}

void UidMap::updateApp(const String16& app_16, const int32_t& uid, const int64_t& versionCode) {
    updateApp(getElapsedRealtimeNs(), app_16, uid, versionCode);
}

void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid,
                       const int64_t& versionCode) {
    vector<wp<PackageInfoListener>> broadcastList;
    string appName = string(String8(app_16).string());
    {
        lock_guard<mutex> lock(mMutex);

        mChanges.emplace_back(false, timestamp, appName, uid, versionCode);
        mBytesUsed += kBytesChangeRecord;
        ensureBytesUsedBelowLimit();
        StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
        StatsdStats::getInstance().setUidMapChanges(mChanges.size());

        auto range = mMap.equal_range(int(uid));
        bool found = false;
        for (auto it = range.first; it != range.second; ++it) {
            // If we find the exact same app name and uid, update the app version directly.
            if (it->second.packageName == appName) {
                it->second.versionCode = versionCode;
                found = true;
                break;
            }
        }
        if (!found) {
            // Otherwise, we need to add an app at this uid.
            mMap.insert(make_pair(uid, AppData(appName, versionCode)));
        }
        getListenerListCopyLocked(&broadcastList);
    }

    for (auto weakPtr : broadcastList) {
        auto strongPtr = weakPtr.promote();
        if (strongPtr != NULL) {
            strongPtr->notifyAppUpgrade(timestamp, appName, uid, versionCode);
        }
    }
}

void UidMap::ensureBytesUsedBelowLimit() {
    size_t limit;
    if (maxBytesOverride <= 0) {
        limit = StatsdStats::kMaxBytesUsedUidMap;
    } else {
        limit = maxBytesOverride;
    }
    while (mBytesUsed > limit) {
        ALOGI("Bytes used %zu is above limit %zu, need to delete something", mBytesUsed, limit);
        if (mSnapshots.size() > 0) {
            mBytesUsed -= mSnapshots.front().bytes;
            mSnapshots.pop_front();
            StatsdStats::getInstance().noteUidMapDropped(1, 0);
        } else if (mChanges.size() > 0) {
            mBytesUsed -= kBytesChangeRecord;
            mChanges.pop_front();
            StatsdStats::getInstance().noteUidMapDropped(0, 1);
        }
    }
}

void UidMap::removeApp(const String16& app_16, const int32_t& uid) {
    removeApp(getElapsedRealtimeNs(), app_16, uid);
}

void UidMap::getListenerListCopyLocked(vector<wp<PackageInfoListener>>* output) {
    for (auto weakIt = mSubscribers.begin(); weakIt != mSubscribers.end();) {
        auto strongPtr = weakIt->promote();
        if (strongPtr != NULL) {
            output->push_back(*weakIt);
            weakIt++;
        } else {
            weakIt = mSubscribers.erase(weakIt);
            VLOG("The UidMap listener is gone, remove it now");
        }
    }
}

void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid) {
    vector<wp<PackageInfoListener>> broadcastList;
    string app = string(String8(app_16).string());
    {
        lock_guard<mutex> lock(mMutex);

        mChanges.emplace_back(true, timestamp, app, uid, 0);
        mBytesUsed += kBytesChangeRecord;
        ensureBytesUsedBelowLimit();
        StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
        StatsdStats::getInstance().setUidMapChanges(mChanges.size());

        auto range = mMap.equal_range(int(uid));
        for (auto it = range.first; it != range.second; ++it) {
            if (it->second.packageName == app) {
                mMap.erase(it);
                break;
            }
        }
        getListenerListCopyLocked(&broadcastList);
    }

    for (auto weakPtr : broadcastList) {
        auto strongPtr = weakPtr.promote();
        if (strongPtr != NULL) {
            strongPtr->notifyAppRemoved(timestamp, app, uid);
        }
    }
}

void UidMap::addListener(wp<PackageInfoListener> producer) {
    lock_guard<mutex> lock(mMutex);  // Lock for updates
    mSubscribers.insert(producer);
}

void UidMap::removeListener(wp<PackageInfoListener> producer) {
    lock_guard<mutex> lock(mMutex);  // Lock for updates
    mSubscribers.erase(producer);
}

void UidMap::assignIsolatedUid(int isolatedUid, int parentUid) {
    lock_guard<mutex> lock(mIsolatedMutex);

    mIsolatedUidMap[isolatedUid] = parentUid;
}

void UidMap::removeIsolatedUid(int isolatedUid, int parentUid) {
    lock_guard<mutex> lock(mIsolatedMutex);

    auto it = mIsolatedUidMap.find(isolatedUid);
    if (it != mIsolatedUidMap.end()) {
        mIsolatedUidMap.erase(it);
    }
}

int UidMap::getHostUidOrSelf(int uid) const {
    lock_guard<mutex> lock(mIsolatedMutex);

    auto it = mIsolatedUidMap.find(uid);
    if (it != mIsolatedUidMap.end()) {
        return it->second;
    }
    return uid;
}

void UidMap::clearOutput() {
    mSnapshots.clear();
    mChanges.clear();
    // Also update the guardrail trackers.
    StatsdStats::getInstance().setUidMapChanges(0);
    StatsdStats::getInstance().setUidMapSnapshots(1);
    mBytesUsed = 0;
    StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
}

int64_t UidMap::getMinimumTimestampNs() {
    int64_t m = 0;
    for (auto it : mLastUpdatePerConfigKey) {
        if (m == 0) {
            m = it.second;
        } else if (it.second < m) {
            m = it.second;
        }
    }
    return m;
}

size_t UidMap::getBytesUsed() const {
    return mBytesUsed;
}

void UidMap::appendUidMap(const ConfigKey& key, ProtoOutputStream* proto) {
    appendUidMap(getElapsedRealtimeNs(), key, proto);
}

void UidMap::appendUidMap(const int64_t& timestamp, const ConfigKey& key,
                          ProtoOutputStream* proto) {
    lock_guard<mutex> lock(mMutex);  // Lock for updates

    for (const ChangeRecord& record : mChanges) {
        if (record.timestampNs > mLastUpdatePerConfigKey[key]) {
            uint64_t changesToken =
                    proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CHANGES);
            proto->write(FIELD_TYPE_BOOL | FIELD_ID_CHANGE_DELETION, (bool)record.deletion);
            proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_TIMESTAMP,
                         (long long)record.timestampNs);
            proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PACKAGE, record.package);
            proto->write(FIELD_TYPE_INT32 | FIELD_ID_CHANGE_UID, (int)record.uid);
            proto->write(FIELD_TYPE_INT32 | FIELD_ID_CHANGE_VERSION, (int)record.version);
            proto->end(changesToken);
        }
    }

    bool atLeastOneSnapshot = false;
    unsigned int count = 0;
    for (const SnapshotRecord& record : mSnapshots) {
        // Ensure that we include at least the latest snapshot.
        if ((count == mSnapshots.size() - 1 && !atLeastOneSnapshot) ||
            record.timestampNs > mLastUpdatePerConfigKey[key]) {
            uint64_t snapshotsToken =
                    proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SNAPSHOTS);
            atLeastOneSnapshot = true;
            count++;
            proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_TIMESTAMP,
                         (long long)record.timestampNs);
            for (const SnapshotPackageInfo& info : record.infos) {
                uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
                                              FIELD_ID_SNAPSHOT_PACKAGE_INFO);
                proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_NAME, info.package);
                proto->write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION, info.version);
                proto->write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_UID, info.uid);
                proto->end(token);
            }
            proto->end(snapshotsToken);
        }
    }

    int64_t prevMin = getMinimumTimestampNs();
    mLastUpdatePerConfigKey[key] = timestamp;
    int64_t newMin = getMinimumTimestampNs();

    if (newMin > prevMin) {  // Delete anything possible now that the minimum has
                             // moved forward.
        int64_t cutoff_nanos = newMin;
        for (auto it_snapshots = mSnapshots.begin(); it_snapshots != mSnapshots.end();) {
            if (it_snapshots->timestampNs < cutoff_nanos) {
                mBytesUsed -= it_snapshots->bytes;
                it_snapshots = mSnapshots.erase(it_snapshots);
            } else {
                ++it_snapshots;
            }
        }
        for (auto it_changes = mChanges.begin(); it_changes != mChanges.end();) {
            if (it_changes->timestampNs < cutoff_nanos) {
                mBytesUsed -= kBytesChangeRecord;
                it_changes = mChanges.erase(it_changes);
            } else {
                ++it_changes;
            }
        }

        if (mSnapshots.size() == 0) {
            // Produce another snapshot. This results in extra data being uploaded but
            // helps ensure we can re-construct the UID->app name, versionCode mapping
            // in server.
            vector<const SnapshotPackageInfo> infos;
            for (const auto& it : mMap) {
                infos.emplace_back(it.second.packageName, it.second.versionCode, it.first);
            }

            mSnapshots.emplace_back(timestamp, infos);
            mBytesUsed += mSnapshots.back().bytes;
        }
    }
    StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
    StatsdStats::getInstance().setUidMapChanges(mChanges.size());
    StatsdStats::getInstance().setUidMapSnapshots(mSnapshots.size());
}

void UidMap::printUidMap(FILE* out) const {
    lock_guard<mutex> lock(mMutex);

    for (auto it : mMap) {
        fprintf(out, "%s, v%" PRId64 " (%i)\n", it.second.packageName.c_str(),
                it.second.versionCode, it.first);
    }
}

void UidMap::OnConfigUpdated(const ConfigKey& key) {
    mLastUpdatePerConfigKey[key] = -1;

    // Ensure there is at least one snapshot available since this configuration also needs to know
    // what all the uid's represent.
    if (mSnapshots.size() == 0) {
        sp<IStatsCompanionService> statsCompanion = nullptr;
        // Get statscompanion service from service manager
        const sp<IServiceManager> sm(defaultServiceManager());
        if (sm != nullptr) {
            const String16 name("statscompanion");
            statsCompanion = interface_cast<IStatsCompanionService>(sm->checkService(name));
            if (statsCompanion == nullptr) {
                ALOGW("statscompanion service unavailable!");
                return;
            }
            statsCompanion->triggerUidSnapshot();
        }
    }
}

void UidMap::OnConfigRemoved(const ConfigKey& key) {
    mLastUpdatePerConfigKey.erase(key);
}

set<int32_t> UidMap::getAppUid(const string& package) const {
    lock_guard<mutex> lock(mMutex);

    set<int32_t> results;
    for (const auto& pair : mMap) {
        if (pair.second.packageName == package) {
            results.insert(pair.first);
        }
    }
    return results;
}

// Note not all the following AIDs are used as uids. Some are used only for gids.
// It's ok to leave them in the map, but we won't ever see them in the log's uid field.
// App's uid starts from 10000, and will not overlap with the following AIDs.
const std::map<string, uint32_t> UidMap::sAidToUidMapping = {{"AID_ROOT", 0},
                                                             {"AID_SYSTEM", 1000},
                                                             {"AID_RADIO", 1001},
                                                             {"AID_BLUETOOTH", 1002},
                                                             {"AID_GRAPHICS", 1003},
                                                             {"AID_INPUT", 1004},
                                                             {"AID_AUDIO", 1005},
                                                             {"AID_CAMERA", 1006},
                                                             {"AID_LOG", 1007},
                                                             {"AID_COMPASS", 1008},
                                                             {"AID_MOUNT", 1009},
                                                             {"AID_WIFI", 1010},
                                                             {"AID_ADB", 1011},
                                                             {"AID_INSTALL", 1012},
                                                             {"AID_MEDIA", 1013},
                                                             {"AID_DHCP", 1014},
                                                             {"AID_SDCARD_RW", 1015},
                                                             {"AID_VPN", 1016},
                                                             {"AID_KEYSTORE", 1017},
                                                             {"AID_USB", 1018},
                                                             {"AID_DRM", 1019},
                                                             {"AID_MDNSR", 1020},
                                                             {"AID_GPS", 1021},
                                                             // {"AID_UNUSED1", 1022},
                                                             {"AID_MEDIA_RW", 1023},
                                                             {"AID_MTP", 1024},
                                                             // {"AID_UNUSED2", 1025},
                                                             {"AID_DRMRPC", 1026},
                                                             {"AID_NFC", 1027},
                                                             {"AID_SDCARD_R", 1028},
                                                             {"AID_CLAT", 1029},
                                                             {"AID_LOOP_RADIO", 1030},
                                                             {"AID_MEDIA_DRM", 1031},
                                                             {"AID_PACKAGE_INFO", 1032},
                                                             {"AID_SDCARD_PICS", 1033},
                                                             {"AID_SDCARD_AV", 1034},
                                                             {"AID_SDCARD_ALL", 1035},
                                                             {"AID_LOGD", 1036},
                                                             {"AID_SHARED_RELRO", 1037},
                                                             {"AID_DBUS", 1038},
                                                             {"AID_TLSDATE", 1039},
                                                             {"AID_MEDIA_EX", 1040},
                                                             {"AID_AUDIOSERVER", 1041},
                                                             {"AID_METRICS_COLL", 1042},
                                                             {"AID_METRICSD", 1043},
                                                             {"AID_WEBSERV", 1044},
                                                             {"AID_DEBUGGERD", 1045},
                                                             {"AID_MEDIA_CODEC", 1046},
                                                             {"AID_CAMERASERVER", 1047},
                                                             {"AID_FIREWALL", 1048},
                                                             {"AID_TRUNKS", 1049},
                                                             {"AID_NVRAM", 1050},
                                                             {"AID_DNS", 1051},
                                                             {"AID_DNS_TETHER", 1052},
                                                             {"AID_WEBVIEW_ZYGOTE", 1053},
                                                             {"AID_VEHICLE_NETWORK", 1054},
                                                             {"AID_MEDIA_AUDIO", 1055},
                                                             {"AID_MEDIA_VIDEO", 1056},
                                                             {"AID_MEDIA_IMAGE", 1057},
                                                             {"AID_TOMBSTONED", 1058},
                                                             {"AID_MEDIA_OBB", 1059},
                                                             {"AID_ESE", 1060},
                                                             {"AID_OTA_UPDATE", 1061},
                                                             {"AID_AUTOMOTIVE_EVS", 1062},
                                                             {"AID_LOWPAN", 1063},
                                                             {"AID_HSM", 1064},
                                                             {"AID_RESERVED_DISK", 1065},
                                                             {"AID_STATSD", 1066},
                                                             {"AID_INCIDENTD", 1067},
                                                             {"AID_SHELL", 2000},
                                                             {"AID_CACHE", 2001},
                                                             {"AID_DIAG", 2002}};

}  // namespace statsd
}  // namespace os
}  // namespace android
