/*
 * Copyright (C) 2020 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.
 */

#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <binder/Binder.h>
#include <sys/types.h>
#include <fstream>
#include <regex>

#include <binderdebug/BinderDebug.h>

namespace android {

static std::string contextToString(BinderDebugContext context) {
    switch (context) {
        case BinderDebugContext::BINDER:
            return "binder";
        case BinderDebugContext::HWBINDER:
            return "hwbinder";
        case BinderDebugContext::VNDBINDER:
            return "vndbinder";
        default:
            return std::string();
    }
}

static status_t scanBinderContext(pid_t pid, const std::string& contextName,
                                  binderdebug::FileReader& fileReader,
                                  std::function<void(const std::string&)> eachLine) {
    if (!fileReader.Open("/dev/binderfs/binder_logs/proc/" + std::to_string(pid))) {
        if (!fileReader.Open("/d/binder/proc/" + std::to_string(pid))) {
            return -errno;
        }
    }

    bool isDesiredContext = false;
    std::string line;
    while (fileReader.GetLine(line)) {
        if (base::StartsWith(line, "context")) {
            isDesiredContext = base::Split(line, " ").back() == contextName;
            continue;
        }
        if (!isDesiredContext) {
            continue;
        }
        eachLine(line);
    }
    return OK;
}

// Examples of what we are looking at:
// node 66730: u00007590061890e0 c0000759036130950 pri 0:120 hs 1 hw 1 ls 0 lw 0 is 2 iw 2 tr 1 proc 2300 1790
// thread 2999: l 00 need_return 1 tr 0
#ifndef BINDER_DEBUG_TEST
static
#endif
        status_t getBinderPidInfo(BinderDebugContext context, pid_t pid,
                                  std::unique_ptr<binderdebug::FileReader> fileReader,
                                  BinderPidInfo* pidInfo) {
    std::smatch match;
    static const std::regex kReferencePrefix("^\\s*node \\d+:\\s+u([0-9a-f]+)\\s+c([0-9a-f]+)\\s+");
    static const std::regex kThreadPrefix("^\\s*thread \\d+:\\s+l\\s+(\\d)(\\d)");
    std::string contextStr = contextToString(context);
    status_t ret = scanBinderContext(pid, contextStr, *fileReader, [&](const std::string& line) {
        if (base::StartsWith(line, "  node ")) {
            std::vector<std::string> splitString = base::Tokenize(line, " ");
            bool pids = false;
            uint64_t ptr = 0;
            for (const auto& token : splitString) {
                if (base::StartsWith(token, "u")) {
                    const std::string ptrString = "0x" + token.substr(1);
                    if (!::android::base::ParseUint(ptrString.c_str(), &ptr)) {
                        LOG(ERROR) << "Failed to parse pointer: " << ptrString;
                        return;
                    }
                } else {
                    // The last numbers in the line after "proc" are all client PIDs
                    if (token == "proc") {
                        pids = true;
                    } else if (pids) {
                        int32_t pid;
                        if (!::android::base::ParseInt(token, &pid)) {
                            LOG(ERROR) << "Failed to parse pid int: " << token;
                            return;
                        }
                        if (ptr == 0) {
                            LOG(ERROR) << "We failed to parse the pointer, so we can't add the refPids";
                            return;
                        }
                        pidInfo->refPids[ptr].push_back(pid);
                    }
                }
            }
        } else if (base::StartsWith(line, "  thread ")) {
            auto pos = line.find("l ");
            if (pos != std::string::npos) {
                // "1" is waiting in binder driver
                // "2" is poll. It's impossible to tell if these are in use.
                //     and HIDL default code doesn't use it.
                bool isInUse = line.at(pos + 2) != '1';
                // "0" is a thread that has called into binder
                // "1" is looper thread
                // "2" is main looper thread
                bool isBinderThread = line.at(pos + 3) != '0';
                if (!isBinderThread) {
                    return;
                }
                if (isInUse) {
                    pidInfo->threadUsage++;
                }

                pidInfo->threadCount++;
            }
        }
    });
    return ret;
}

status_t getBinderPidInfo(BinderDebugContext context, pid_t pid, BinderPidInfo* pidInfo) {
    return getBinderPidInfo(context, pid, std::make_unique<binderdebug::FileReader>(), pidInfo);
}

// Examples of what we are looking at:
// ref 52493: desc 910 node 52492 s 1 w 1 d 0000000000000000
// node 29413: u00007803fc982e80 c000078042c982210 pri 0:139 hs 1 hw 1 ls 0 lw 0 is 2 iw 2 tr 1 proc 488 683
#ifndef BINDER_DEBUG_TEST
static
#endif
        status_t getBinderClientPids(BinderDebugContext context, pid_t pid, pid_t servicePid,
                                     int32_t handle,
                                     std::unique_ptr<binderdebug::FileReader> fileReader,
                                     std::vector<pid_t>* pids) {
    std::string contextStr = contextToString(context);
    int32_t node = -1;
    status_t ret = scanBinderContext(pid, contextStr, *fileReader, [&](const std::string& line) {
        if (!base::StartsWith(line, "  ref ")) return;

        std::vector<std::string> splitString = base::Tokenize(line, " ");

        if (splitString.size() > 5) {
            int32_t desc;
            if (!::android::base::ParseInt(splitString[3].c_str(), &desc)) {
                LOG(ERROR) << "Failed to parse desc int: " << splitString[3];
                return;
            }
            if (handle != desc) {
                return;
            }
            // We only expect live node desc to match handle
            if (!::android::base::ParseInt(splitString[5].c_str(), &node)) {
                LOG(ERROR) << "Failed to parse node int: " << splitString[5];
                return;
            }
            LOG(INFO) << "Parsed the node: " << node;
            return;
        }

        LOG(ERROR) << "Failed to parse binder_logs ref entry with size: " << splitString.size();
    });

    // Don't bother scanning for clients if node hasn't been parsed
    if (ret != OK || node < 0) {
        return ret;
    }

    ret = scanBinderContext(servicePid, contextStr, *fileReader, [&](const std::string& line) {
        if (!base::StartsWith(line, "  node ")) return;

        std::vector<std::string> splitString = base::Tokenize(line, " ");
        // Ignore lines for "node work" and nodes without a count
        if (splitString[1] == "work") {
            return;
        }

        // remove the colon
        const std::string nodeString = splitString[1].substr(0, splitString[1].size() - 1);
        int32_t matchedNode;
        if (!::android::base::ParseInt(nodeString.c_str(), &matchedNode)) {
            LOG(ERROR) << "Failed to parse node int: " << nodeString;
            return;
        }

        if (node != matchedNode) {
            return;
        }

        bool pidsSection = false;
        for (const auto& token : splitString) {
            if (token == "proc") {
                pidsSection = true;
            } else if (pidsSection == true) {
                int32_t pid;
                if (!::android::base::ParseInt(token.c_str(), &pid)) {
                    LOG(ERROR) << "Failed to parse PID int: " << token;
                    return;
                }
                pids->push_back(pid);
            }
        }
    });
    return ret;
}

status_t getBinderClientPids(BinderDebugContext context, pid_t pid, pid_t servicePid,
                             int32_t handle, std::vector<pid_t>* pids) {
    return getBinderClientPids(context, pid, servicePid, handle,
                               std::make_unique<binderdebug::FileReader>(), pids);
}

#ifndef BINDER_DEBUG_TEST
static
#endif
        status_t getBinderTransactions(pid_t pid,
                                       std::unique_ptr<binderdebug::FileReader> fileReader,
                                       std::string& transactionsOutput) {
    // Hashed log will contain scrambled node ptr and cookie information, so
    // try to access standard logs first.
    static const char* kBinderTransactionLogPaths[] = {
            "/dev/binderfs/binder_logs/transactions",
            "/d/binder/transactions",
            "/dev/binderfs/binder_logs/transactions_hashed",
    };

    for (auto& path : kBinderTransactionLogPaths) {
        if (fileReader->Open(path)) {
            break;
        }
    }

    if (!fileReader->IsOpen()) {
        LOG(ERROR) << "Could not open /dev/binderfs/binder_logs/transactions. "
                   << "Likely a permissions issue. errno: " << errno;
        return -errno;
    }

    // Reset errno to avoid the confusing "No such file or directory" error
    // message in case we failed to open any of the paths
    errno = 0;

    std::string line;
    while (fileReader->GetLine(line)) {
        // The section for this pid ends with another "proc <pid>" for another
        // process. There is only one entry per pid so we can stop looking after
        // we've grabbed the whole section
        if (base::StartsWith(line, "proc " + std::to_string(pid))) {
            do {
                transactionsOutput += line + '\n';
            } while (fileReader->GetLine(line) && !base::StartsWith(line, "proc "));
            return OK;
        }
    }

    return NAME_NOT_FOUND;
}

status_t getBinderTransactions(pid_t pid, std::string& transactionsOutput) {
    return getBinderTransactions(pid, std::make_unique<binderdebug::FileReader>(),
                                 transactionsOutput);
}

} // namespace  android
