//#define LOG_NDEBUG 0
#define LOG_TAG "hidl_test_java_native"

#include <android-base/logging.h>

#include <android/hardware/tests/baz/1.0/IBaz.h>

#include <gtest/gtest.h>
#include <hidl/IServiceManager.h>
#include <hidl/Status.h>
#include <hwbinder/IPCThreadState.h>
#include <hwbinder/ProcessState.h>

using ::android::sp;
using ::android::Thread;
using ::android::hardware::tests::baz::V1_0::IBase;
using ::android::hardware::tests::baz::V1_0::IBaz;
using ::android::hardware::tests::baz::V1_0::IBazCallback;

using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::hardware::Return;
using ::android::hardware::Void;

struct BazCallback : public IBazCallback {
    Return<void> heyItsMe(const sp<IBazCallback> &cb) override;
};

Return<void> BazCallback::heyItsMe(
        const sp<IBazCallback> &cb) {
    LOG(INFO) << "SERVER: heyItsMe cb = " << cb.get();

    return Void();
}

struct Baz : public IBaz {
    Return<void> someBaseMethod() override;

    Return<void> someOtherBaseMethod(
            const IBaz::Foo &foo, someOtherBaseMethod_cb _hidl_cb) override;

    Return<bool> someBoolMethod(bool x) override;

    Return<void> someBoolArrayMethod(
            const bool x[3], someBoolArrayMethod_cb _hidl_cb) override;

    Return<void> someBoolVectorMethod(
            const hidl_vec<bool> &x, someBoolVectorMethod_cb _hidl_cb) override;

    Return<void> doSomethingElse(
            const int32_t param[15], doSomethingElse_cb _hidl_cb) override;

    Return<void> doThis(float param) override;

    Return<int32_t> doThatAndReturnSomething(int64_t param) override;

    Return<double> doQuiteABit(
            int32_t a,
            int64_t b,
            float c,
            double d) override;

    Return<void> doStuffAndReturnAString(
            doStuffAndReturnAString_cb _hidl_cb) override;

    Return<void> mapThisVector(
            const hidl_vec<int32_t>& param, mapThisVector_cb _hidl_cb) override;

    Return<void> callMe(const sp<IBazCallback>& cb) override;
    Return<IBaz::SomeEnum> useAnEnum(IBaz::SomeEnum zzz) override;

    Return<void> haveSomeStrings(
            const hidl_string array[3], haveSomeStrings_cb _hidl_cb) override;

    Return<void> haveAStringVec(
            const hidl_vec<hidl_string>& vector,
            haveAStringVec_cb _hidl_cb) override;

    Return<void> returnABunchOfStrings(returnABunchOfStrings_cb _hidl_cb) override;
};

Return<void> Baz::someBaseMethod() {
    LOG(INFO) << "Baz::someBaseMethod";

    return Void();
}

using std::to_string;

static std::string to_string(const IBaz::Foo::Bar &bar);
static std::string to_string(const IBaz::Foo &foo);
static std::string to_string(const hidl_string &s);
static std::string to_string(bool x);

template<class T>
static std::string array_to_string(const T *array, size_t size) {
    std::string out;
    out = "[";
    for (size_t i = 0; i < size; ++i) {
        if (i > 0) {
            out += ", ";
        }
        out += to_string(array[i]);
    }
    out += "]";

    return out;
}

template<class T>
static std::string to_string(const hidl_vec<T> &vec) {
    return array_to_string(&vec[0], vec.size());
}

static std::string to_string(bool x) {
    return x ? "true" : "false";
}

static std::string to_string(const hidl_string &s) {
    return std::string("'") + s.c_str() + "'";
}

static std::string to_string(const IBaz::Foo::Bar &bar) {
    std::string out;
    out = "Bar(";
    out += "z = " + to_string(bar.z) + ", ";
    out += "s = '" + std::string(bar.s.c_str()) + "'";
    out += ")";

    return out;
}

static std::string to_string(const IBaz::Foo &foo) {
    std::string out;
    out = "Foo(";
    out += "x = " + to_string(foo.x) + ", ";
    out += "y = " + to_string(foo.y) + ", ";
    out += "aaa = " + to_string(foo.aaa);
    out += ")";

    return out;
}

Return<void> Baz::someOtherBaseMethod(
        const IBaz::Foo &foo, someOtherBaseMethod_cb _hidl_cb) {
    LOG(INFO) << "Baz::someOtherBaseMethod "
              << to_string(foo);

    _hidl_cb(foo);

    return Void();
}

Return<bool> Baz::someBoolMethod(bool x) {
    LOG(INFO) << "Baz::someBoolMethod(" << to_string(x) << ")";

    return !x;
}

Return<void> Baz::someBoolArrayMethod(
        const bool x[3], someBoolArrayMethod_cb _hidl_cb) {
    LOG(INFO) << "Baz::someBoolArrayMethod("
        << to_string(x[0])
        << ", "
        << to_string(x[1])
        << ", "
        << to_string(x[2])
        << ")";

    bool out[4];
    out[0] = !x[0];
    out[1] = !x[1];
    out[2] = !x[2];
    out[3] = true;

    _hidl_cb(out);

    return Void();
}

Return<void> Baz::someBoolVectorMethod(
        const hidl_vec<bool> &x, someBoolVectorMethod_cb _hidl_cb) {
    LOG(INFO) << "Baz::someBoolVectorMethod(" << to_string(x) << ")";

    hidl_vec<bool> out;
    out.resize(x.size());
    for (size_t i = 0; i < x.size(); ++i) {
        out[i] = !x[i];
    }

    _hidl_cb(out);

    return Void();
}

Return<void> Baz::doSomethingElse(
        const int32_t param[15], doSomethingElse_cb _hidl_cb) {
    LOG(INFO) << "Baz::doSomethingElse(...)";

    int32_t result[32] = { 0 };
    for (size_t i = 0; i < 15; ++i) {
        result[i] = 2 * param[i];
        result[15 + i] = param[i];
    }
    result[30] = 1;
    result[31] = 2;

    _hidl_cb(result);

    return Void();
}

Return<void> Baz::doThis(float param) {
    LOG(INFO) << "Baz::doThis(" << param << ")";

    return Void();
}

Return<int32_t> Baz::doThatAndReturnSomething(int64_t param) {
    LOG(INFO) << "Baz::doThatAndReturnSomething(" << param << ")";

    return 666;
}

Return<double> Baz::doQuiteABit(
        int32_t a,
        int64_t b,
        float c,
        double d) {
    LOG(INFO) << "Baz::doQuiteABit("
              << a
              << ", "
              << b
              << ", "
              << c
              << ", "
              << d
              << ")";

    return 666.5;
}

Return<void> Baz::doStuffAndReturnAString(
        doStuffAndReturnAString_cb _hidl_cb) {
    LOG(INFO) << "doStuffAndReturnAString";

    hidl_string s;
    s = "Hello, world!";

    _hidl_cb(s);

    return Void();
}

Return<void> Baz::mapThisVector(
        const hidl_vec<int32_t>& param, mapThisVector_cb _hidl_cb) {
    LOG(INFO) << "mapThisVector";

    hidl_vec<int32_t> out;
    out.resize(param.size());
    for (size_t i = 0; i < param.size(); ++i) {
        out[i] = param[i] * 2;
    }

    _hidl_cb(out);

    return Void();
}

Return<void> Baz::callMe(const sp<IBazCallback>& cb) {
    LOG(INFO) << "callMe " << cb.get();

    if (cb != NULL) {
        sp<IBazCallback> my_cb = new BazCallback;
        cb->heyItsMe(my_cb);
    }

    return Void();
}

Return<IBaz::SomeEnum> Baz::useAnEnum(IBaz::SomeEnum zzz) {
    LOG(INFO) << "useAnEnum " << (int)zzz;

    return SomeEnum::goober;
}

Return<void> Baz::haveSomeStrings(
        const hidl_string array[3], haveSomeStrings_cb _hidl_cb) {
    LOG(INFO) << "haveSomeStrings("
              << array_to_string(array, 3)
              << ")";

    hidl_string result[2];
    result[0] = "Hello";
    result[1] = "World";

    _hidl_cb(result);

    return Void();
}

Return<void> Baz::haveAStringVec(
        const hidl_vec<hidl_string>& vector,
        haveAStringVec_cb _hidl_cb) {
    LOG(INFO) << "haveAStringVec(" << to_string(vector) << ")";

    hidl_vec<hidl_string> result;
    result.resize(2);

    result[0] = "Hello";
    result[1] = "World";

    _hidl_cb(result);

    return Void();
}

Return<void> Baz::returnABunchOfStrings(returnABunchOfStrings_cb _hidl_cb) {
    hidl_string eins; eins = "Eins";
    hidl_string zwei; zwei = "Zwei";
    hidl_string drei; drei = "Drei";
    _hidl_cb(eins, zwei, drei);

    return Void();
}

static void usage(const char *me) {
    fprintf(stderr, "%s [-c]lient | [-s]erver\n", me);
}

struct HidlEnvironment : public ::testing::Environment {
    void SetUp() override {
    }

    void TearDown() override {
    }
};

struct HidlTest : public ::testing::Test {
    sp<IBaz> baz;

    void SetUp() override {
        using namespace ::android::hardware;

        const hidl_version kVersion = make_hidl_version(1, 0);

        baz = IBaz::getService("baz", kVersion);

        CHECK(baz != NULL);
    }

    void TearDown() override {
    }
};

template <typename T>
static void EXPECT_OK(::android::hardware::Return<T> ret) {
    EXPECT_TRUE(ret.getStatus().isOk());
}

TEST_F(HidlTest, BazSomeBaseMethodTest) {
    EXPECT_OK(baz->someBaseMethod());
}

TEST_F(HidlTest, BazSomeOtherBaseMethodTest) {
    IBase::Foo foo;
    foo.x = 1;
    foo.y.z = 2.5;
    foo.y.s = "Hello, world";

    foo.aaa.resize(5);
    for (size_t i = 0; i < foo.aaa.size(); ++i) {
        foo.aaa[i].z = 1.0f + (float)i * 0.01f;
        foo.aaa[i].s = ("Hello, world " + std::to_string(i)).c_str();
    }

    EXPECT_OK(
            baz->someOtherBaseMethod(
                foo,
                [&](const auto &result) {
                    EXPECT_EQ(
                        to_string(result),
                        "Foo(x = 1, "
                            "y = Bar(z = 2.500000, s = 'Hello, world'), "
                            "aaa = [Bar(z = 1.000000, s = 'Hello, world 0'), "
                                   "Bar(z = 1.010000, s = 'Hello, world 1'), "
                                   "Bar(z = 1.020000, s = 'Hello, world 2'), "
                                   "Bar(z = 1.030000, s = 'Hello, world 3'), "
                                   "Bar(z = 1.040000, s = 'Hello, world 4')])");
                }));
}

TEST_F(HidlTest, BazSomeBoolMethodTest) {
    auto result = baz->someBoolMethod(true);
    EXPECT_OK(result);
    EXPECT_EQ(to_string(result), "false");
}

TEST_F(HidlTest, BazSomeBoolArrayMethodTest) {
    const bool someBoolArray[3] = { true, false, true };

    EXPECT_OK(
            baz->someBoolArrayMethod(
                someBoolArray,
                [&](const auto &result) {
                    EXPECT_EQ(
                        array_to_string(result, 4),
                        "[false, true, false, true]");
                }));
}

TEST_F(HidlTest, BazSomeBoolVectorMethodTest) {
    hidl_vec<bool> someBoolVector;
    someBoolVector.resize(4);
    for (size_t i = 0; i < someBoolVector.size(); ++i) {
        someBoolVector[i] = ((i & 1) == 0);
    }

    EXPECT_OK(
            baz->someBoolVectorMethod(
                someBoolVector,
                [&](const auto &result) {
                    EXPECT_EQ(
                        to_string(result), "[false, true, false, true]");
                }));
}

TEST_F(HidlTest, BazDoThisMethodTest) {
    EXPECT_OK(baz->doThis(1.0f));
}

TEST_F(HidlTest, BazDoThatAndReturnSomethingMethodTest) {
    auto result = baz->doThatAndReturnSomething(1);
    EXPECT_OK(result);
    EXPECT_EQ(to_string(result), "666");
}

TEST_F(HidlTest, BazDoQuiteABitMethodTest) {
    auto result = baz->doQuiteABit(1, 2ll, 3.0f, 4.0);

    EXPECT_OK(result);
    EXPECT_EQ(to_string(result), "666.500000");
}

TEST_F(HidlTest, BazDoSomethingElseMethodTest) {
    int32_t param[15];
    for (size_t i = 0; i < 15; ++i) {
        param[i] = i;
    }

    EXPECT_OK(
            baz->doSomethingElse(
                param,
                [&](const auto &result) {
                    EXPECT_EQ(
                        array_to_string(result, 32),
                        "[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, "
                        "28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, "
                        "1, 2]");
                }));
}

TEST_F(HidlTest, BazDoStuffAndReturnAStringMethodTest) {
    EXPECT_OK(
            baz->doStuffAndReturnAString(
                [&](const auto &result) {
                    EXPECT_EQ(to_string(result), "'Hello, world!'");
                }));
}

TEST_F(HidlTest, BazMapThisVectorMethodTest) {
    hidl_vec<int32_t> vec_param;
    vec_param.resize(15);
    for (size_t i = 0; i < 15; ++i) {
        vec_param[i] = i;
    }

    EXPECT_OK(
            baz->mapThisVector(
                vec_param,
                [&](const auto &result) {
                    EXPECT_EQ(
                        array_to_string(&result[0], result.size()),
                        "[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, "
                        "28]");
                }));
}

TEST_F(HidlTest, BazCallMeMethodTest) {
    EXPECT_OK(baz->callMe(new BazCallback()));
}

TEST_F(HidlTest, BazUseAnEnumMethodTest) {
    auto result = baz->useAnEnum(IBaz::SomeEnum::bar);

    EXPECT_OK(result);
    EXPECT_TRUE(result == IBaz::SomeEnum::quux);
}

TEST_F(HidlTest, BazHaveSomeStringsMethodTest) {
    hidl_string string_params[3];
    string_params[0] = "one";
    string_params[1] = "two";
    string_params[2] = "three";

    EXPECT_OK(
            baz->haveSomeStrings(
                string_params,
                [&](const auto &result) {
                    EXPECT_EQ(
                        array_to_string(result, 2), "['Hello', 'World']");
                }));
}

TEST_F(HidlTest, BazHaveAStringVecMethodTest) {
    hidl_vec<hidl_string> string_vec;
    string_vec.resize(4);
    string_vec[0] = "Uno";
    string_vec[1] = "Dos";
    string_vec[2] = "Tres";
    string_vec[3] = "Cuatro";

    EXPECT_OK(
            baz->haveAStringVec(
                string_vec,
                [&](const auto &result) {
                    EXPECT_EQ(
                        array_to_string(&result[0], result.size()),
                        "['Hello', 'World']");
                }));
}

TEST_F(HidlTest, BazReturnABunchOfStringsMethodTest) {
    EXPECT_OK(
            baz->returnABunchOfStrings(
                [&](const auto &a, const auto &b, const auto &c) {
                    EXPECT_EQ(
                        to_string(a) + ", " + to_string(b) + ", " + to_string(c),
                        "'Eins', 'Zwei', 'Drei'");
                }));
}

int main(int argc, char **argv) {
    using namespace android::hardware;

    const char *me = argv[0];

    bool wantClient = false;
    bool wantServer = false;

    int res;
    while ((res = getopt(argc, argv, "chs")) >= 0) {
        switch (res) {
            case 'c':
            {
                wantClient = true;
                break;
            }

            case 's':
            {
                wantServer = true;
                break;
            }

            case '?':
            case 'h':
            default:
            {
                usage(me);
                exit(1);
                break;
            }
        }
    }

    if ((!wantClient && !wantServer) || (wantClient && wantServer)) {
        usage(me);
        exit(1);
    }

    if (wantClient) {
        ::testing::AddGlobalTestEnvironment(new HidlEnvironment);
        ::testing::InitGoogleTest(&argc, argv);
        int status = RUN_ALL_TESTS();
        return status;
    } else {
        sp<Baz> baz = new Baz;

        const hidl_version kVersion = make_hidl_version(1, 0);

        baz->registerAsService("baz", kVersion);

        ProcessState::self()->startThreadPool();
        ProcessState::self()->setThreadPoolMaxThreadCount(0);
        IPCThreadState::self()->joinThreadPool();
    }

    return 0;
}

