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

#define LOG_TAG "libhwbinder_benchmark"

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <iostream>

#include <log/log.h>
#include <utils/StrongPointer.h>

#include <benchmark/benchmark.h>
#include <hidl/Status.h>
#include <hidl/ServiceManagement.h>

#include <android/hardware/tests/libhwbinder/1.0/IBenchmark.h>

// libutils:
using android::OK;
using android::sp;
using android::status_t;

// libhidl:
using android::hardware::defaultServiceManager;
using android::hardware::Return;
using android::hardware::Void;
using android::hardware::hidl_vec;

// Standard library
using std::cerr;
using std::cout;
using std::endl;
using std::string;
using std::unique_ptr;
using std::vector;

// Generated HIDL files
using android::hardware::tests::libhwbinder::V1_0::IBenchmark;

const char gServiceName[] = "android.hardware.tests.libhwbinder.IBenchmark";

static bool startServer() {
    sp<IBenchmark> service = IBenchmark::getService(gServiceName, true);
    status_t status = service->registerAsService(gServiceName);

    if (status != ::android::OK) {
        ALOGE("Failed to register service %s.", gServiceName);
        exit(EXIT_FAILURE);
    }

    return 0;
}

static void BM_sendVec(benchmark::State& state, sp<IBenchmark> service) {
    // Prepare data to IPC
    hidl_vec<uint8_t> data_vec;
    data_vec.resize(state.range(0));
    for (int i = 0; i < state.range(0); i++) {
       data_vec[i] = i % 256;
    }
    // Start running
    while (state.KeepRunning()) {
       service->sendVec(data_vec, [&] (const auto &/*res*/) {
               });
    }
}

static void BM_sendVec_passthrough(benchmark::State& state) {
    // getService automatically retries
    sp<IBenchmark> service = IBenchmark::getService(gServiceName, true /* getStub */);
    if (service == nullptr) {
        state.SkipWithError("Failed to retrieve benchmark service.");
    }
    if (service->isRemote()) {
        state.SkipWithError("Benchmark service is remote.");
    }
    BM_sendVec(state, service);
}

static void BM_sendVec_binderize(benchmark::State& state) {
    // getService automatically retries
    sp<IBenchmark> service = IBenchmark::getService(gServiceName);
    if (service == nullptr) {
        state.SkipWithError("Failed to retrieve benchmark service.");
    }
    if (!service->isRemote()) {
        state.SkipWithError("Unable to fetch remote benchmark service.");
    }
    BM_sendVec(state, service);
}

int main(int argc, char* argv []) {
    setenv("TREBLE_TESTING_OVERRIDE", "true", true);

    enum HwBinderMode {
        kBinderize = 0,
        kPassthrough = 1,
    };
    HwBinderMode mode = HwBinderMode::kBinderize;

    // Parse arguments.
    for (int i = 1; i < argc; i++) {
        if (string(argv[i]) == "-m") {
            if (!strcmp(argv[i + 1], "PASSTHROUGH")) {
                mode = HwBinderMode::kPassthrough;
            }
            break;
        }
    }
    if (mode == HwBinderMode::kBinderize) {
        BENCHMARK(BM_sendVec_binderize)->RangeMultiplier(2)->Range(4, 65536);
    } else {
        BENCHMARK(BM_sendVec_passthrough)->RangeMultiplier(2)->Range(4, 65536);
    }

    ::benchmark::Initialize(&argc, argv);

    pid_t pid = fork();
    if (pid == 0) {
        // Child, start benchmarks
        ::benchmark::RunSpecifiedBenchmarks();
    } else {
        startServer();
        while (true) {
            int stat, retval;
            retval = wait(&stat);
            if (retval == -1 && errno == ECHILD) {
                break;
            }
        }
    };
}
