/*
 * Copyright (C) 2020 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 "message_queue.h"

#include <thread>

#include "common_runtime_test.h"
#include "thread-current-inl.h"
#include "runtime.h"

namespace art {

class MessageQueueTest : public CommonRuntimeTest {
 protected:
  MessageQueueTest() {
    this->use_boot_image_ = true;  // Make the Runtime creation cheaper.
  }
};

namespace {

// Define some message types
struct EmptyMessage {};
struct IntMessage {
  int value;
};
struct OtherIntMessage {
  int other_value;
};
struct TwoIntMessage {
  int value1;
  int value2;
};
struct StringMessage {
  std::string message;
};

using TestMessageQueue =
    MessageQueue<EmptyMessage, IntMessage, OtherIntMessage, TwoIntMessage, StringMessage>;

}  // namespace

TEST_F(MessageQueueTest, SendReceiveTest) {
  TestMessageQueue queue;

  queue.SendMessage(EmptyMessage{});
  ASSERT_TRUE(std::holds_alternative<EmptyMessage>(queue.ReceiveMessage()));

  queue.SendMessage(IntMessage{42});
  ASSERT_TRUE(std::holds_alternative<IntMessage>(queue.ReceiveMessage()));

  queue.SendMessage(OtherIntMessage{43});
  ASSERT_TRUE(std::holds_alternative<OtherIntMessage>(queue.ReceiveMessage()));

  queue.SendMessage(TwoIntMessage{1, 2});
  ASSERT_TRUE(std::holds_alternative<TwoIntMessage>(queue.ReceiveMessage()));

  queue.SendMessage(StringMessage{"Hello, World!"});
  ASSERT_TRUE(std::holds_alternative<StringMessage>(queue.ReceiveMessage()));
}

TEST_F(MessageQueueTest, TestTimeout) {
  TestMessageQueue queue;

  constexpr uint64_t kDuration = 500;

  const auto start = MilliTime();
  queue.SetTimeout(kDuration);
  ASSERT_TRUE(std::holds_alternative<TimeoutExpiredMessage>(queue.ReceiveMessage()));
  const auto elapsed = MilliTime() - start;

  ASSERT_GT(elapsed, kDuration);
}

TEST_F(MessageQueueTest, TwoWayMessaging) {
  CHECK(Runtime::Current() != nullptr);  // Runtime is needed by Mutex.

  TestMessageQueue queue1;
  TestMessageQueue queue2;

  std::thread thread{[&]() {
    // Tell the parent thread we are running.
    queue1.SendMessage(EmptyMessage{});

    // Wait for a message from the parent thread.
    queue2.ReceiveMessage();
  }};

  queue1.ReceiveMessage();
  queue2.SendMessage(EmptyMessage{});

  thread.join();
}

TEST_F(MessageQueueTest, SwitchReceiveTest) {
  TestMessageQueue queue;

  queue.SendMessage(EmptyMessage{});
  queue.SendMessage(IntMessage{42});
  queue.SendMessage(OtherIntMessage{43});
  queue.SendMessage(TwoIntMessage{1, 2});
  queue.SendMessage(StringMessage{"Hello, World!"});
  queue.SetTimeout(500);

  bool empty_received = false;
  bool int_received = false;
  bool other_int_received = false;
  bool two_int_received = false;
  bool string_received = false;
  bool timeout_received = false;

  while (!(empty_received && int_received && other_int_received && two_int_received &&
           string_received && timeout_received)) {
    queue.SwitchReceive(
        [&]([[maybe_unused]] const EmptyMessage& message) {
          ASSERT_FALSE(empty_received);
          empty_received = true;
        },
        [&](const IntMessage& message) {
          ASSERT_FALSE(int_received);
          int_received = true;

          ASSERT_EQ(message.value, 42);
        },
        [&](const OtherIntMessage& message) {
          ASSERT_FALSE(other_int_received);
          other_int_received = true;

          ASSERT_EQ(message.other_value, 43);
        },
        // The timeout message is here to make sure the cases can go in any order
        [&]([[maybe_unused]] const TimeoutExpiredMessage& message) {
          ASSERT_FALSE(timeout_received);
          timeout_received = true;
        },
        [&](const TwoIntMessage& message) {
          ASSERT_FALSE(two_int_received);
          two_int_received = true;

          ASSERT_EQ(message.value1, 1);
          ASSERT_EQ(message.value2, 2);
        },
        [&](const StringMessage& message) {
          ASSERT_FALSE(string_received);
          string_received = true;

          ASSERT_EQ(message.message, "Hello, World!");
        });
  }
}

TEST_F(MessageQueueTest, SwitchReceiveAutoTest) {
  TestMessageQueue queue;

  queue.SendMessage(EmptyMessage{});
  queue.SendMessage(IntMessage{42});
  queue.SendMessage(OtherIntMessage{43});
  queue.SendMessage(TwoIntMessage{1, 2});
  queue.SendMessage(StringMessage{"Hello, World!"});
  queue.SetTimeout(500);

  int pending_messages = 6;

  while (pending_messages > 0) {
    queue.SwitchReceive([&]([[maybe_unused]] auto message) { pending_messages--; });
  }
}

TEST_F(MessageQueueTest, SwitchReceivePartialAutoTest) {
  TestMessageQueue queue;

  queue.SendMessage(EmptyMessage{});
  queue.SendMessage(IntMessage{42});
  queue.SendMessage(OtherIntMessage{43});
  queue.SendMessage(TwoIntMessage{1, 2});
  queue.SendMessage(StringMessage{"Hello, World!"});
  queue.SetTimeout(500);

  bool running = true;
  while (running) {
    queue.SwitchReceive(
        [&](const StringMessage& message) {
          ASSERT_EQ(message.message, "Hello, World!");
          running = false;
        },
        [&]([[maybe_unused]] const auto& message) {
          const bool is_string{std::is_same<StringMessage, decltype(message)>()};
          ASSERT_FALSE(is_string);
        });
  }
}

TEST_F(MessageQueueTest, SwitchReceiveReturn) {
  TestMessageQueue queue;

  queue.SendMessage(EmptyMessage{});

  ASSERT_TRUE(
      queue.SwitchReceive<bool>([&]([[maybe_unused]] const EmptyMessage& message) { return true; },
                                [&]([[maybe_unused]] const auto& message) { return false; }));

  queue.SendMessage(IntMessage{42});

  ASSERT_FALSE(
      queue.SwitchReceive<bool>([&]([[maybe_unused]] const EmptyMessage& message) { return true; },
                                [&]([[maybe_unused]] const auto& message) { return false; }));
}

TEST_F(MessageQueueTest, ReceiveInOrder) {
  TestMessageQueue queue;

  std::vector<TestMessageQueue::Message> messages{
      EmptyMessage{},
      IntMessage{42},
      OtherIntMessage{43},
      TwoIntMessage{1, 2},
      StringMessage{"Hello, World!"},
  };

  // Send the messages
  for (const auto& message : messages) {
    queue.SendMessage(message);
  }
  queue.SetTimeout(500);

  // Receive the messages. Make sure they came in order, except for the TimeoutExpiredMessage, which
  // can come at any time.
  bool received_timeout = false;
  size_t i = 0;
  while (i < messages.size()) {
    auto message = queue.ReceiveMessage();
    if (std::holds_alternative<TimeoutExpiredMessage>(message)) {
      ASSERT_FALSE(received_timeout);
      received_timeout = true;
    } else {
      ASSERT_EQ(message.index(), messages[i].index());
      i++;
    }
  }
  if (!received_timeout) {
    // If we have not received the timeout yet, receive one more message and make sure it's the
    // timeout.
    ASSERT_TRUE(std::holds_alternative<TimeoutExpiredMessage>(queue.ReceiveMessage()));
  }
}

}  // namespace art
