// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 <gflags/gflags.h>
#include <sys/resource.h>
#include <algorithm>
#include <atomic>
#include <chrono>
#include <cstdint>
#include <cstring>
#include <exception>
#include <functional>
#include <iomanip>
#include <iostream>
#include <memory>
#include <mutex>
#include <string>
#include <system_error>
#include <thread>
#include <vector>
#include "butil/config.h"
#include "butil/endpoint.h"
#include "butil/iobuf.h"
#include "butil/memory/scope_guard.h"
#include "brpc/channel.h"
#include "brpc/controller.h"
#include "brpc/errno.pb.h"
#include "brpc/server.h"
#include "bthread/bthread.h"
#include "echo.brpc.fb.h"
#include "echo_pb.pb.h"

#if !BRPC_WITH_FLATBUFFERS
#error "benchmark_fb requires a FlatBuffers-enabled brpc library"
#endif

DEFINE_string(server, "", "IPv4 endpoint printed by benchmark_fb_server; "
              "a non-loopback address also needs --allow_remote");
DEFINE_bool(allow_remote, false, "Allow a non-loopback --server for cross-host benchmarks");
DEFINE_string(protocol, "fb_rpc", "fb_rpc, or baidu_std for the protobuf control service");
DEFINE_string(connection_type, "single", "single, pooled, or short");
DEFINE_int32(request_count, 16, "Count mode: total requests across all threads, 1..1000");
DEFINE_int32(duration_s, 0, "0 selects count mode; 1..3600 runs a timed benchmark");
DEFINE_int32(warmup_s, 0, "Timed mode: unmeasured warm-up seconds, 0..600");
DEFINE_int32(thread_num, 2, "Concurrent synchronous callers: 1..16, or 1..1024 when timed");
DEFINE_int32(request_size, 64, "Bytes in the optional request string, 0..1048576");
DEFINE_int32(attachment_size, 0, "Bytes in the echoed attachment, 0..1048576");
DEFINE_int32(timeout_ms, 1500, "Per-RPC timeout, 1..5000 milliseconds");
DEFINE_int32(deadline_ms, 30000, "Count mode: overall client deadline, 1..120000 milliseconds");
DEFINE_bool(omit_message, false, "Omit the optional string rather than sending an empty string");
DEFINE_bool(use_bthread, false, "Run callers as bthreads instead of pthreads");
DEFINE_bool(corrupt_request, false, "fb_rpc only: send an invalid root offset and "
            "require schema rejection");
DEFINE_int32(fail_worker_start_at, -1, "Testing only: fail to start the worker with "
             "this 0-based index, -1 disables");

namespace {
using brpc::flatbuffers::Message;
using brpc::flatbuffers::MessageBuilder;
using Clock = std::chrono::steady_clock;

// Result of one RPC: kSuccess, kRejected (expected schema rejection) or kFailed.
enum CallResult { kSuccess, kRejected, kFailed };
// Arguments: request ID, timeout in ms, RPC latency in us (out), error (out).
using CallFn = std::function<CallResult(uint64_t, int64_t, int64_t*, std::string*)>;

std::string MakeBytes(size_t size, unsigned multiplier) {
    std::string bytes(size, '\0');
    for (size_t i = 0; i < size; ++i) {
        bytes[i] = static_cast<char>((i * multiplier) % 251);
    }
    return bytes;
}

Message MakeRequest(uint64_t request_id, const std::string& text) {
    MessageBuilder builder(text.size() + 256);
    const auto message = FLAGS_omit_message ?
        ::flatbuffers::Offset<::flatbuffers::String>() :
        builder.CreateString(text.data(), text.size());
    builder.Finish(benchmark_fb::CreateRequest(builder, request_id, message));
    Message request = builder.ReleaseMessage();
    if (FLAGS_corrupt_request) {
        // Damage only the schema, not FRPC framing, so the server's generated
        // dispatcher must reject the request before invoking the service.
        memset(request.mutable_data(), 0xff, sizeof(::flatbuffers::uoffset_t));
    }
    return request;
}

bool CheckResponse(const Message& response, uint64_t request_id,
                   const std::string& text, const butil::IOBuf& attachment,
                   const brpc::Controller& cntl) {
    if (!response.Verify<benchmark_fb::Response>()) {
        return false;
    }
    const auto* output = response.GetRoot<benchmark_fb::Response>();
    if (output->request_id() != request_id ||
        output->attachment_size() != attachment.size() ||
        !cntl.response_attachment().equals(attachment)) {
        return false;
    }
    if (FLAGS_omit_message) {
        return output->message() == nullptr;
    }
    return output->message() != nullptr && output->message()->size() == text.size() &&
        memcmp(output->message()->data(), text.data(), text.size()) == 0;
}

bool CheckPbResponse(const benchmark_fb_pb::Response& response, uint64_t request_id,
                     const std::string& text, const butil::IOBuf& attachment,
                     const brpc::Controller& cntl) {
    if (response.request_id() != request_id ||
        response.attachment_size() != attachment.size() ||
        !cntl.response_attachment().equals(attachment)) {
        return false;
    }
    if (FLAGS_omit_message) {
        return !response.has_message();
    }
    return response.has_message() && response.message() == text;
}

bool IsLoopback(const std::string& server) {
    return server.compare(0, 10, "127.0.0.1:") == 0;
}

bool ValidFlags(butil::EndPoint* endpoint) {
    const bool timed = FLAGS_duration_s > 0;
    return (IsLoopback(FLAGS_server) || FLAGS_allow_remote) &&
        butil::str2endpoint(FLAGS_server.c_str(), endpoint) == 0 && endpoint->port > 0 &&
        (FLAGS_protocol == "fb_rpc" || FLAGS_protocol == "baidu_std") &&
        !(FLAGS_corrupt_request && (FLAGS_protocol != "fb_rpc" || timed)) &&
        (FLAGS_connection_type == "single" || FLAGS_connection_type == "pooled" ||
         FLAGS_connection_type == "short") &&
        // Short connections in a timed run exhaust local ports in TIME_WAIT.
        !(timed && FLAGS_connection_type == "short") &&
        FLAGS_request_count >= 1 && FLAGS_request_count <= 1000 &&
        FLAGS_duration_s >= 0 && FLAGS_duration_s <= 3600 &&
        FLAGS_warmup_s >= 0 && FLAGS_warmup_s <= 600 && (timed || FLAGS_warmup_s == 0) &&
        FLAGS_thread_num >= 1 && FLAGS_thread_num <= (timed ? 1024 : 16) &&
        FLAGS_fail_worker_start_at >= -1 && FLAGS_fail_worker_start_at < FLAGS_thread_num &&
        FLAGS_request_size >= 0 && FLAGS_request_size <= 1024 * 1024 &&
        FLAGS_attachment_size >= 0 && FLAGS_attachment_size <= 1024 * 1024 &&
        FLAGS_timeout_ms >= 1 && FLAGS_timeout_ms <= 5000 &&
        FLAGS_deadline_ms >= 1 && FLAGS_deadline_ms <= 120000;
}

struct Shared {
    std::atomic<bool> failed{false};
    std::mutex error_mutex;
    void Fail(const std::string& message) {
        if (!failed.exchange(true)) {
            std::lock_guard<std::mutex> lock(error_mutex);
            std::cerr << message << '\n';
        }
    }
};

// Builds one synchronous RPC for the selected protocol. Both protocols carry
// the same request string and attachment and verify every echoed byte. Only
// the RPC itself is timed, not building the request or checking the reply.
CallFn MakeCall(brpc::Channel* channel, const std::string& text,
                const butil::IOBuf& attachment) {
    if (FLAGS_protocol == "baidu_std") {
        auto stub = std::make_shared<benchmark_fb_pb::BenchmarkService_Stub>(channel);
        return [stub, &text, &attachment](uint64_t request_id, int64_t timeout_ms,
                                          int64_t* latency_us, std::string* error) {
            benchmark_fb_pb::Request request;
            request.set_request_id(request_id);
            if (!FLAGS_omit_message) {
                request.set_message(text);
            }
            benchmark_fb_pb::Response response;
            brpc::Controller cntl;
            cntl.set_timeout_ms(timeout_ms);
            cntl.request_attachment().append(attachment);
            const auto begin = Clock::now();
            stub->Echo(&cntl, &request, &response, nullptr);
            *latency_us = std::chrono::duration_cast<std::chrono::microseconds>(
                Clock::now() - begin).count();
            if (cntl.Failed()) {
                *error = "RPC failed: " + cntl.ErrorText();
                return kFailed;
            }
            if (!CheckPbResponse(response, request_id, text, attachment, cntl)) {
                *error = "Response fields, optional string or attachment mismatch";
                return kFailed;
            }
            return kSuccess;
        };
    }
    // Generated stub methods route through Channel::FBCallMethod.
    auto stub = std::make_shared<benchmark_fb::BenchmarkService::Stub>(channel);
    return [stub, &text, &attachment](uint64_t request_id, int64_t timeout_ms,
                                      int64_t* latency_us, std::string* error) {
        const Message request = MakeRequest(request_id, text);
        Message response;
        brpc::Controller cntl;
        cntl.set_timeout_ms(timeout_ms);
        cntl.request_attachment().append(attachment);
        const auto begin = Clock::now();
        stub->Echo(&cntl, &request, &response, nullptr);
        *latency_us = std::chrono::duration_cast<std::chrono::microseconds>(
            Clock::now() - begin).count();
        if (FLAGS_corrupt_request) {
            // The generated dispatcher rejects the schema through the generic
            // RpcController::SetFailed(string), which is -1 on the wire today.
            // Also accept EINTERNAL, what baidu_std maps -1 to. Timeouts and
            // connection errors do not count.
            if (!cntl.Failed() ||
                (cntl.ErrorCode() != -1 && cntl.ErrorCode() != brpc::EINTERNAL) ||
                response.size() != 0 || !cntl.response_attachment().empty()) {
                *error = "Expected server schema rejection; error=" + cntl.ErrorText();
                return kFailed;
            }
            return kRejected;
        }
        if (cntl.Failed()) {
            *error = "RPC failed: " + cntl.ErrorText();
            return kFailed;
        }
        if (!CheckResponse(response, request_id, text, attachment, cntl)) {
            *error = "Response schema, fields, optional string or attachment mismatch";
            return kFailed;
        }
        return kSuccess;
    };
}

struct BthreadArg {
    Shared* shared;
    const std::function<void(int)>* body;
    int index;
};

void* BthreadEntry(void* raw) {
    std::unique_ptr<BthreadArg> arg(static_cast<BthreadArg*>(raw));
    try {
        (*arg->body)(arg->index);
    } catch (const std::exception& error) {
        arg->shared->Fail(std::string("Client worker failed: ") + error.what());
    }
    return nullptr;
}

// Runs `body' on FLAGS_thread_num workers and returns how many started. A
// worker that cannot start marks `shared' failed; the others still run.
int RunWorkers(Shared* shared, const std::function<void(int)>& body) {
    int started = 0;
    if (FLAGS_use_bthread) {
        std::vector<bthread_t> ids(FLAGS_thread_num, INVALID_BTHREAD);
        for (int i = 0; i < FLAGS_thread_num; ++i) {
            auto* arg = new BthreadArg{shared, &body, i};
            if (i == FLAGS_fail_worker_start_at ||
                bthread_start_background(&ids[i], nullptr, BthreadEntry, arg) != 0) {
                delete arg;
                ids[i] = INVALID_BTHREAD;
                shared->Fail("Cannot start bthread worker");
            } else {
                ++started;
            }
        }
        for (bthread_t id : ids) {
            if (id != INVALID_BTHREAD) {
                bthread_join(id, nullptr);
            }
        }
        return started;
    }
    std::vector<std::thread> workers;
    workers.reserve(FLAGS_thread_num);
    try {
        for (int i = 0; i < FLAGS_thread_num; ++i) {
            if (i == FLAGS_fail_worker_start_at) {
                throw std::system_error(EAGAIN, std::generic_category(),
                                        "simulated start failure");
            }
            workers.emplace_back([shared, &body, i] {
                try {
                    body(i);
                } catch (const std::exception& error) {
                    shared->Fail(std::string("Client worker failed: ") + error.what());
                }
            });
        }
    } catch (const std::exception& error) {
        shared->Fail(std::string("Cannot start client worker: ") + error.what());
    }
    for (auto& thread : workers) {
        thread.join();
    }
    return static_cast<int>(workers.size());
}

// Bounded functional mode used by smoke.py.
int RunCount(const CallFn& call) {
    const auto deadline = Clock::now() + std::chrono::milliseconds(FLAGS_deadline_ms);
    std::atomic<int> next{0};
    std::atomic<int> successes{0};
    std::atomic<int> expected_rejections{0};
    Shared shared;
    RunWorkers(&shared, [&](int) {
        while (!shared.failed.load()) {
            const int index = next.fetch_add(1);
            if (index >= FLAGS_request_count) {
                break;
            }
            const int64_t remaining = std::chrono::duration_cast<
                std::chrono::milliseconds>(deadline - Clock::now()).count();
            if (remaining <= 0) {
                shared.Fail("Overall client deadline exceeded");
                break;
            }
            std::string error;
            int64_t latency_us = 0;
            const CallResult result = call(static_cast<uint64_t>(index) + 1,
                std::min<int64_t>(FLAGS_timeout_ms, remaining), &latency_us, &error);
            if (result == kFailed) {
                shared.Fail(error);
                break;
            }
            ++(result == kRejected ? expected_rejections : successes);
        }
    });
    const int completed = successes.load() + expected_rejections.load();
    if (completed != FLAGS_request_count) {
        shared.Fail("Not all requested RPCs completed");
    }
    std::cout << "{\"completed\":" << completed
              << ",\"successes\":" << successes.load()
              << ",\"expected_rejections\":" << expected_rejections.load()
              << ",\"failures\":" << (shared.failed.load() ? 1 : 0) << "}\n";
    return shared.failed.load() ? 1 : 0;
}

double CpuSeconds() {
    rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    return usage.ru_utime.tv_sec + usage.ru_stime.tv_sec +
        (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / 1e6;
}

// Per-caller latency histogram in microseconds with fixed memory, however
// long the run. Values below 128 are exact; larger ones fall into 128 buckets
// per power of two, so a percentile is reported at most 1/128 above the
// recorded value. Average and maximum are exact.
class LatencyHistogram {
public:
    LatencyHistogram() : _counts(kBuckets, 0) {}

    void Add(uint32_t us) {
        ++_counts[IndexOf(us)];
        ++_count;
        _sum += us;
        _max = std::max(_max, us);
    }

    void Merge(const LatencyHistogram& other) {
        for (size_t i = 0; i < kBuckets; ++i) {
            _counts[i] += other._counts[i];
        }
        _count += other._count;
        _sum += other._sum;
        _max = std::max(_max, other._max);
    }

    uint64_t count() const { return _count; }
    double average() const { return _count ? _sum / _count : 0; }
    uint32_t max() const { return _max; }

    // Nearest-rank percentile, reported as the upper bound of its bucket.
    uint32_t Percentile(double p) const {
        if (_count == 0) {
            return 0;
        }
        const uint64_t rank = static_cast<uint64_t>(p * (_count - 1) + 0.5);
        uint64_t seen = 0;
        for (size_t i = 0; i < kBuckets; ++i) {
            seen += _counts[i];
            if (seen > rank) {
                return std::min(UpperBound(i), _max);
            }
        }
        return _max;
    }

private:
    static constexpr int kSubBits = 7;
    static constexpr uint32_t kSub = 1u << kSubBits;
    static constexpr size_t kBuckets = kSub + (32 - kSubBits) * kSub;

    static size_t IndexOf(uint32_t us) {
        if (us < kSub) {
            return us;
        }
        const int shift = 31 - __builtin_clz(us) - kSubBits;
        return kSub + shift * kSub + ((us >> shift) - kSub);
    }

    static uint32_t UpperBound(size_t index) {
        if (index < kSub) {
            return static_cast<uint32_t>(index);
        }
        const size_t shift = (index - kSub) / kSub;
        const uint64_t mantissa = kSub + (index - kSub) % kSub;
        return static_cast<uint32_t>(std::min<uint64_t>(
            ((mantissa + 1) << shift) - 1, UINT32_MAX));
    }

    std::vector<uint64_t> _counts;
    uint64_t _count = 0;
    double _sum = 0;
    uint32_t _max = 0;
};

// Sleeps for `seconds' unless SIGINT/SIGTERM arrives first. Returns false if
// the user asked to quit.
bool SleepUnlessAskedToQuit(int seconds) {
    const auto until = Clock::now() + std::chrono::seconds(seconds);
    while (!brpc::IsAskedToQuit()) {
        const auto now = Clock::now();
        if (now >= until) {
            return true;
        }
        std::this_thread::sleep_for(std::min<Clock::duration>(
            until - now, std::chrono::milliseconds(100)));
    }
    return false;
}

// Closed-loop benchmark: every caller keeps one RPC in flight for
// warmup_s + duration_s and records per-call latency in the measured window.
// SIGINT/SIGTERM closes the window early and fails the run.
int RunTimed(const CallFn& call) {
    Shared shared;
    std::vector<LatencyHistogram> latencies(FLAGS_thread_num);
    std::atomic<uint64_t> next_id{1};
    std::atomic<bool> measuring{false};
    std::atomic<bool> stop{false};
    std::atomic<int64_t> failures{0};
    bool interrupted = false;
    // Sample time and CPU at the same boundaries that open and close the
    // counting window. Waiting for in-flight RPCs after `stop' is excluded.
    Clock::time_point measure_begin;
    Clock::time_point measure_end;
    double cpu_begin = 0;
    double cpu_end = 0;
    // Install brpc's SIGINT/SIGTERM handlers before any call starts.
    brpc::IsAskedToQuit();
    std::thread timer([&] {
        bool completed = SleepUnlessAskedToQuit(FLAGS_warmup_s);
        measure_begin = Clock::now();
        cpu_begin = CpuSeconds();
        measuring = true;
        completed = completed && SleepUnlessAskedToQuit(FLAGS_duration_s);
        measure_end = Clock::now();
        stop = true;
        cpu_end = CpuSeconds();
        interrupted = !completed;
    });
    // Never leave `timer' joinable, which would terminate, if RunWorkers throws.
    BRPC_SCOPE_EXIT {
        if (timer.joinable()) {
            timer.join();
        }
    };
    const int started_threads = RunWorkers(&shared, [&](int index) {
        LatencyHistogram& histogram = latencies[index];
        while (!stop.load(std::memory_order_relaxed)) {
            const bool measured = measuring.load(std::memory_order_relaxed);
            int64_t latency_us = 0;
            std::string error;
            const CallResult result = call(next_id.fetch_add(1, std::memory_order_relaxed),
                                           FLAGS_timeout_ms, &latency_us, &error);
            if (result != kSuccess) {
                if (failures.fetch_add(1) == 0) {
                    shared.Fail(error);
                }
                continue;
            }
            if (measured && !stop.load(std::memory_order_relaxed)) {
                histogram.Add(static_cast<uint32_t>(
                    std::min<int64_t>(latency_us, UINT32_MAX)));
            }
        }
    });
    timer.join();
    if (interrupted) {
        shared.Fail("Interrupted; the measured window closed early");
    }
    LatencyHistogram all;
    for (const auto& histogram : latencies) {
        all.Merge(histogram);
    }
    const double seconds = std::chrono::duration<double>(measure_end - measure_begin).count();
    const double qps = seconds > 0 ? all.count() / seconds : 0;
    const double payload = static_cast<double>(FLAGS_omit_message ? 0 : FLAGS_request_size) +
        FLAGS_attachment_size;
    std::cout << std::fixed << std::setprecision(1)
              << "{\"mode\":\"timed\",\"protocol\":\"" << FLAGS_protocol
              << "\",\"connection_type\":\"" << FLAGS_connection_type
              << "\",\"use_bthread\":" << (FLAGS_use_bthread ? "true" : "false")
              << ",\"thread_num\":" << FLAGS_thread_num
              << ",\"started_threads\":" << started_threads
              << ",\"request_size\":" << FLAGS_request_size
              << ",\"attachment_size\":" << FLAGS_attachment_size
              << ",\"seconds\":" << seconds
              << ",\"requests\":" << all.count()
              << ",\"failures\":" << failures.load()
              << ",\"qps\":" << qps
              << ",\"payload_mib_per_s\":" << qps * payload / (1024.0 * 1024.0)
              << ",\"avg_us\":" << all.average()
              << ",\"p50_us\":" << all.Percentile(0.50)
              << ",\"p90_us\":" << all.Percentile(0.90)
              << ",\"p99_us\":" << all.Percentile(0.99)
              << ",\"p999_us\":" << all.Percentile(0.999)
              << ",\"max_us\":" << all.max()
              << ",\"client_cpu_cores\":" << std::setprecision(3)
              << (seconds > 0 ? (cpu_end - cpu_begin) / seconds : 0)
              << "}\n";
    // A run with fewer callers than requested is not a valid benchmark.
    return !shared.failed.load() && failures.load() == 0 &&
           started_threads == FLAGS_thread_num && all.count() > 0 ? 0 : 1;
}

int RunClient(const butil::EndPoint& endpoint) {
    brpc::Channel channel;
    brpc::ChannelOptions options;
    options.protocol = FLAGS_protocol;
    options.connection_type = FLAGS_connection_type;
    options.timeout_ms = FLAGS_timeout_ms;
    options.connect_timeout_ms = std::min(FLAGS_timeout_ms, 1000);
    options.max_retry = 0;
    if (channel.Init(endpoint, &options) != 0) {
        std::cerr << "Cannot initialize " << FLAGS_protocol << " channel\n";
        return 1;
    }
    const std::string text = MakeBytes(FLAGS_omit_message ? 0 : FLAGS_request_size, 31);
    // Every call appends this IOBuf by reference instead of copying the bytes.
    butil::IOBuf attachment;
    attachment.append(MakeBytes(FLAGS_attachment_size, 17));
    const CallFn call = MakeCall(&channel, text, attachment);
    return FLAGS_duration_s > 0 ? RunTimed(call) : RunCount(call);
}
}  // namespace

int main(int argc, char* argv[]) {
    GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
    butil::EndPoint endpoint;
    if (!ValidFlags(&endpoint)) {
        std::cerr << "Invalid flags; --server=127.0.0.1:PORT is required unless "
                     "--allow_remote is set. See --help and README.md for bounded "
                     "parameter ranges.\n";
        return 2;
    }
    try {
        return RunClient(endpoint);
    } catch (const std::exception& error) {
        std::cerr << "Client failed: " << error.what() << '\n';
        return 1;
    }
}
