/*
 * 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 <aidl/android/aidl/loggable/ILoggableInterface.h>

#include <functional>

#include <android/binder_auto_utils.h>
#include <android/binder_manager.h>
#include <gtest/gtest.h>

#include <aidl/android/aidl/fixedsizearray/FixedSizeArrayExample.h>
#include <aidl/android/aidl/tests/ITestService.h>
#include <aidl/android/aidl/tests/RecursiveList.h>
#include <aidl/android/aidl/tests/Union.h>

using aidl::android::aidl::fixedsizearray::FixedSizeArrayExample;
using BnRepeatFixedSizeArray =
    aidl::android::aidl::fixedsizearray::FixedSizeArrayExample::BnRepeatFixedSizeArray;
using BpRepeatFixedSizeArray =
    aidl::android::aidl::fixedsizearray::FixedSizeArrayExample::BpRepeatFixedSizeArray;
using IntParcelable = aidl::android::aidl::fixedsizearray::FixedSizeArrayExample::IntParcelable;
using IRepeatFixedSizeArray =
    aidl::android::aidl::fixedsizearray::FixedSizeArrayExample::IRepeatFixedSizeArray;
using BnEmptyInterface =
    aidl::android::aidl::fixedsizearray::FixedSizeArrayExample::BnEmptyInterface;
using aidl::android::aidl::tests::BackendType;
using aidl::android::aidl::tests::ITestService;
using aidl::android::aidl::tests::RecursiveList;
using aidl::android::aidl::tests::Union;
using android::OK;
using ndk::AParcel_readData;
using ndk::AParcel_writeData;
using ndk::ScopedAStatus;
using ndk::SharedRefBase;
using ndk::SpAIBinder;

struct AidlTest : testing::Test {
  template <typename T>
  std::shared_ptr<T> getService() {
    ndk::SpAIBinder binder = ndk::SpAIBinder(AServiceManager_getService(T::descriptor));
    return T::fromBinder(binder);
  }
};

// TODO(b/196454897): copy more tests from aidl_test_client

TEST_F(AidlTest, ReverseRecursiveList) {
  std::unique_ptr<RecursiveList> head;
  for (int i = 0; i < 10; i++) {
    auto node = std::make_unique<RecursiveList>();
    node->value = i;
    node->next = std::move(head);
    head = std::move(node);
  }
  // head: [9, 8, ... 0]

  RecursiveList reversed;
  auto status = getService<ITestService>()->ReverseList(*head, &reversed);
  ASSERT_TRUE(status.isOk());

  // reversed should be [0, 1, .. 9]
  RecursiveList* cur = &reversed;
  for (int i = 0; i < 10; i++) {
    EXPECT_EQ(i, cur->value);
    cur = cur->next.get();
  }
  EXPECT_EQ(nullptr, cur);
}

TEST_F(AidlTest, GetUnionTags) {
  std::vector<Union> unions;
  std::vector<Union::Tag> tags;
  // test empty
  auto status = getService<ITestService>()->GetUnionTags(unions, &tags);
  ASSERT_TRUE(status.isOk());
  EXPECT_EQ(tags, (std::vector<Union::Tag>{}));
  // test non-empty
  unions.push_back(Union::make<Union::n>());
  unions.push_back(Union::make<Union::ns>());
  status = getService<ITestService>()->GetUnionTags(unions, &tags);
  ASSERT_TRUE(status.isOk());
  EXPECT_EQ(tags, (std::vector<Union::Tag>{Union::n, Union::ns}));
}

TEST_F(AidlTest, FixedSizeArray) {
  auto parcel = AParcel_create();

  FixedSizeArrayExample p;
  p.byteMatrix[0][0] = 0;
  p.byteMatrix[0][1] = 1;
  p.byteMatrix[1][0] = 2;
  p.byteMatrix[1][1] = 3;
  p.floatMatrix[0][0] = 0.f;
  p.floatMatrix[0][1] = 1.f;
  p.floatMatrix[1][0] = 2.f;
  p.floatMatrix[1][1] = 3.f;
  EXPECT_EQ(OK, p.writeToParcel(parcel));

  AParcel_setDataPosition(parcel, 0);

  FixedSizeArrayExample q;
  EXPECT_EQ(OK, q.readFromParcel(parcel));
  EXPECT_EQ(p, q);

  AParcel_delete(parcel);
}

TEST_F(AidlTest, FixedSizeArrayWithValuesAtNullableFields) {
  auto parcel = AParcel_create();

  FixedSizeArrayExample p;
  p.boolNullableArray = std::array<bool, 2>{true, false};
  p.byteNullableArray = std::array<uint8_t, 2>{42, 0};
  p.stringNullableArray = std::array<std::optional<std::string>, 2>{"hello", "world"};

  p.boolNullableMatrix.emplace();
  p.boolNullableMatrix->at(0) = std::array<bool, 2>{true, false};
  p.byteNullableMatrix.emplace();
  p.byteNullableMatrix->at(0) = std::array<uint8_t, 2>{42, 0};
  p.stringNullableMatrix.emplace();
  p.stringNullableMatrix->at(0) = std::array<std::optional<std::string>, 2>{"hello", "world"};

  EXPECT_EQ(OK, p.writeToParcel(parcel));

  AParcel_setDataPosition(parcel, 0);

  FixedSizeArrayExample q;
  EXPECT_EQ(OK, q.readFromParcel(parcel));
  EXPECT_EQ(p, q);

  AParcel_delete(parcel);
}

TEST_F(AidlTest, FixedSizeArrayOfBytesShouldBePacked) {
  auto parcel = AParcel_create();

  std::array<std::array<uint8_t, 3>, 2> byte_array;
  byte_array[0] = {1, 2, 3};
  byte_array[1] = {4, 5, 6};
  EXPECT_EQ(OK, AParcel_writeData(parcel, byte_array));

  AParcel_setDataPosition(parcel, 0);

  int32_t len;
  EXPECT_EQ(OK, AParcel_readData(parcel, &len));
  EXPECT_EQ(2, len);
  std::vector<uint8_t> byte_vector;
  EXPECT_EQ(OK, AParcel_readData(parcel, &byte_vector));
  EXPECT_EQ(byte_vector, (std::vector<uint8_t>{1, 2, 3}));
  EXPECT_EQ(OK, AParcel_readData(parcel, &byte_vector));
  EXPECT_EQ(byte_vector, (std::vector<uint8_t>{4, 5, 6}));

  AParcel_delete(parcel);
}

template <typename Service, typename MemFn, typename Input>
void CheckRepeat(Service service, MemFn fn, Input input) {
  Input out1, out2;
  EXPECT_TRUE(std::invoke(fn, service, input, &out1, &out2).isOk());
  EXPECT_EQ(input, out1);
  EXPECT_EQ(input, out2);
}

template <typename T>
std::array<std::array<T, 3>, 2> Make2dArray(std::initializer_list<T> values) {
  std::array<std::array<T, 3>, 2> arr = {};
  auto it = std::begin(values);
  for (auto& row : arr) {
    for (auto& el : row) {
      if (it == std::end(values)) break;
      el = *it++;
    }
  }
  return arr;
}

TEST_F(AidlTest, FixedSizeArrayOverBinder) {
  auto service = getService<IRepeatFixedSizeArray>();

  CheckRepeat(service, &IRepeatFixedSizeArray::RepeatBytes, (std::array<uint8_t, 3>{1, 2, 3}));

  CheckRepeat(service, &IRepeatFixedSizeArray::RepeatInts, (std::array<int32_t, 3>{1, 2, 3}));

  auto binder1 = SharedRefBase::make<BnEmptyInterface>()->asBinder();
  auto binder2 = SharedRefBase::make<BnEmptyInterface>()->asBinder();
  auto binder3 = SharedRefBase::make<BnEmptyInterface>()->asBinder();
  CheckRepeat(service, &IRepeatFixedSizeArray::RepeatBinders,
              (std::array<SpAIBinder, 3>{binder1, binder2, binder3}));

  IntParcelable p1, p2, p3;
  p1.value = 1;
  p2.value = 2;
  p3.value = 3;
  CheckRepeat(service, &IRepeatFixedSizeArray::RepeatParcelables,
              (std::array<IntParcelable, 3>{p1, p2, p3}));

  CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dBytes, Make2dArray<uint8_t>({1, 2, 3}));

  CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dInts, Make2dArray<int32_t>({1, 2, 3}));

  // Not-nullable
  CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dBinders,
              Make2dArray<SpAIBinder>({binder1, binder2, binder3, binder1, binder2, binder3}));

  CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dParcelables,
              Make2dArray<IntParcelable>({p1, p2, p3}));
}
