/*
 * Copyright (C) 2021 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 <sysexits.h>
#include <unistd.h>

#include <iostream>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android/debug/BnAdbCallback.h>
#include <android/debug/IAdbManager.h>
#include <android/os/BnServiceManager.h>
#include <android/os/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/RpcServer.h>

using android::BBinder;
using android::defaultServiceManager;
using android::OK;
using android::RpcServer;
using android::sp;
using android::status_t;
using android::statusToString;
using android::String16;
using android::base::Basename;
using android::base::GetBoolProperty;
using android::base::InitLogging;
using android::base::LogdLogger;
using android::base::LogId;
using android::base::LogSeverity;
using android::base::StdioLogger;
using android::base::StringPrintf;
using std::string_view_literals::operator""sv;

namespace {

const char* kLocalInetAddress = "127.0.0.1";
using ServiceRetriever = decltype(&android::IServiceManager::checkService);
using android::debug::IAdbManager;

int Usage(const char* program) {
    auto basename = Basename(program);
    auto format = R"(dispatch calls to RPC service.
Usage:
  %s [-g] <service_name>
    <service_name>: the service to connect to.
  %s [-g] manager
    Runs an RPC-friendly service that redirects calls to servicemanager.

  -g: use getService() instead of checkService().

  If successful, writes port number and a new line character to stdout, and
  blocks until killed.
  Otherwise, writes error message to stderr and exits with non-zero code.
)";
    LOG(ERROR) << StringPrintf(format, basename.c_str(), basename.c_str());
    return EX_USAGE;
}

int Dispatch(const char* name, const ServiceRetriever& serviceRetriever) {
    auto sm = defaultServiceManager();
    if (nullptr == sm) {
        LOG(ERROR) << "No servicemanager";
        return EX_SOFTWARE;
    }
    auto binder = std::invoke(serviceRetriever, defaultServiceManager(), String16(name));
    if (nullptr == binder) {
        LOG(ERROR) << "No service \"" << name << "\"";
        return EX_SOFTWARE;
    }
    auto rpcServer = RpcServer::make();
    if (nullptr == rpcServer) {
        LOG(ERROR) << "Cannot create RpcServer";
        return EX_SOFTWARE;
    }
    rpcServer->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
    unsigned int port;
    if (status_t status = rpcServer->setupInetServer(kLocalInetAddress, 0, &port); status != OK) {
        LOG(ERROR) << "setupInetServer failed: " << statusToString(status);
        return EX_SOFTWARE;
    }
    auto socket = rpcServer->releaseServer();
    auto keepAliveBinder = sp<BBinder>::make();
    auto status = binder->setRpcClientDebug(std::move(socket), keepAliveBinder);
    if (status != OK) {
        LOG(ERROR) << "setRpcClientDebug failed with " << statusToString(status);
        return EX_SOFTWARE;
    }
    LOG(INFO) << "Finish setting up RPC on service " << name << " on port " << port;

    std::cout << port << std::endl;

    TEMP_FAILURE_RETRY(pause());

    PLOG(FATAL) << "TEMP_FAILURE_RETRY(pause()) exits; this should not happen!";
    __builtin_unreachable();
}

// Wrapper that wraps a BpServiceManager as a BnServiceManager.
class ServiceManagerProxyToNative : public android::os::BnServiceManager {
public:
    ServiceManagerProxyToNative(const sp<android::os::IServiceManager>& impl) : mImpl(impl) {}
    android::binder::Status getService(const std::string&,
                                       android::sp<android::IBinder>*) override {
        // We can't send BpBinder for regular binder over RPC.
        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
    }
    android::binder::Status checkService(const std::string&,
                                         android::sp<android::IBinder>*) override {
        // We can't send BpBinder for regular binder over RPC.
        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
    }
    android::binder::Status addService(const std::string&, const android::sp<android::IBinder>&,
                                       bool, int32_t) override {
        // We can't send BpBinder for RPC over regular binder.
        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
    }
    android::binder::Status listServices(int32_t dumpPriority,
                                         std::vector<std::string>* _aidl_return) override {
        return mImpl->listServices(dumpPriority, _aidl_return);
    }
    android::binder::Status registerForNotifications(
            const std::string&, const android::sp<android::os::IServiceCallback>&) override {
        // We can't send BpBinder for RPC over regular binder.
        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
    }
    android::binder::Status unregisterForNotifications(
            const std::string&, const android::sp<android::os::IServiceCallback>&) override {
        // We can't send BpBinder for RPC over regular binder.
        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
    }
    android::binder::Status isDeclared(const std::string& name, bool* _aidl_return) override {
        return mImpl->isDeclared(name, _aidl_return);
    }
    android::binder::Status getDeclaredInstances(const std::string& iface,
                                                 std::vector<std::string>* _aidl_return) override {
        return mImpl->getDeclaredInstances(iface, _aidl_return);
    }
    android::binder::Status updatableViaApex(const std::string& name,
                                             std::optional<std::string>* _aidl_return) override {
        return mImpl->updatableViaApex(name, _aidl_return);
    }
    android::binder::Status registerClientCallback(
            const std::string&, const android::sp<android::IBinder>&,
            const android::sp<android::os::IClientCallback>&) override {
        // We can't send BpBinder for RPC over regular binder.
        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
    }
    android::binder::Status tryUnregisterService(const std::string&,
                                                 const android::sp<android::IBinder>&) override {
        // We can't send BpBinder for RPC over regular binder.
        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
    }
    android::binder::Status getServiceDebugInfo(
            std::vector<android::os::ServiceDebugInfo>* _aidl_return) override {
        return mImpl->getServiceDebugInfo(_aidl_return);
    }

private:
    sp<android::os::IServiceManager> mImpl;
};

// Workaround for b/191059588.
// TODO(b/191059588): Once we can run RpcServer on single-threaded services,
//   `servicedispatcher manager` should call Dispatch("manager") directly.
int wrapServiceManager(const ServiceRetriever& serviceRetriever) {
    auto sm = defaultServiceManager();
    if (nullptr == sm) {
        LOG(ERROR) << "No servicemanager";
        return EX_SOFTWARE;
    }
    auto service = std::invoke(serviceRetriever, defaultServiceManager(), String16("manager"));
    if (nullptr == service) {
        LOG(ERROR) << "No service called `manager`";
        return EX_SOFTWARE;
    }
    auto interface = android::os::IServiceManager::asInterface(service);
    if (nullptr == interface) {
        LOG(ERROR) << "Cannot cast service called `manager` to IServiceManager";
        return EX_SOFTWARE;
    }

    // Work around restriction that doesn't allow us to send proxy over RPC.
    interface = sp<ServiceManagerProxyToNative>::make(interface);
    service = ServiceManagerProxyToNative::asBinder(interface);

    auto rpcServer = RpcServer::make();
    rpcServer->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
    rpcServer->setRootObject(service);
    unsigned int port;
    if (status_t status = rpcServer->setupInetServer(kLocalInetAddress, 0, &port); status != OK) {
        LOG(ERROR) << "Unable to set up inet server: " << statusToString(status);
        return EX_SOFTWARE;
    }
    LOG(INFO) << "Finish wrapping servicemanager with RPC on port " << port;
    std::cout << port << std::endl;
    rpcServer->join();

    LOG(FATAL) << "Wrapped servicemanager exits; this should not happen!";
    __builtin_unreachable();
}

class AdbCallback : public android::debug::BnAdbCallback {
public:
    android::binder::Status onDebuggingChanged(bool enabled,
                                               android::debug::AdbTransportType) override {
        if (!enabled) {
            LOG(ERROR) << "ADB debugging disabled, exiting.";
            exit(EX_SOFTWARE);
        }
        return android::binder::Status::ok();
    }
};

void exitOnAdbDebuggingDisabled() {
    auto adb = android::waitForService<IAdbManager>(String16("adb"));
    CHECK(adb != nullptr) << "Unable to retrieve service adb";
    auto status = adb->registerCallback(sp<AdbCallback>::make());
    CHECK(status.isOk()) << "Unable to call IAdbManager::registerCallback: " << status;
}

// Log to logd. For warning and more severe messages, also log to stderr.
class ServiceDispatcherLogger {
public:
    void operator()(LogId id, LogSeverity severity, const char* tag, const char* file,
                    unsigned int line, const char* message) {
        mLogdLogger(id, severity, tag, file, line, message);
        if (severity >= LogSeverity::WARNING) {
            std::cout << std::flush;
            std::cerr << Basename(getprogname()) << ": " << message << std::endl;
        }
    }

private:
    LogdLogger mLogdLogger{};
};

} // namespace

int main(int argc, char* argv[]) {
    InitLogging(argv, ServiceDispatcherLogger());

    if (!GetBoolProperty("ro.debuggable", false)) {
        LOG(ERROR) << "servicedispatcher is only allowed on debuggable builds.";
        return EX_NOPERM;
    }
    LOG(WARNING) << "WARNING: servicedispatcher is debug only. Use with caution.";

    int opt;
    ServiceRetriever serviceRetriever = &android::IServiceManager::checkService;
    while (-1 != (opt = getopt(argc, argv, "g"))) {
        switch (opt) {
            case 'g': {
                serviceRetriever = &android::IServiceManager::getService;
            } break;
            default: {
                return Usage(argv[0]);
            }
        }
    }

    android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
    android::ProcessState::self()->startThreadPool();
    exitOnAdbDebuggingDisabled();

    if (optind + 1 != argc) return Usage(argv[0]);
    auto name = argv[optind];

    if (name == "manager"sv) {
        return wrapServiceManager(serviceRetriever);
    }
    return Dispatch(name, serviceRetriever);
}
