/*
 * Copyright (C) 2023 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 "perfetto/ext/base/threading/spawn.h"

#include <optional>

#include "perfetto/ext/base/event_fd.h"
#include "perfetto/ext/base/thread_task_runner.h"
#include "perfetto/ext/base/threading/future.h"
#include "perfetto/ext/base/threading/poll.h"
#include "perfetto/ext/base/threading/util.h"
#include "perfetto/ext/base/unix_task_runner.h"
#include "src/base/test/test_task_runner.h"
#include "test/gtest_and_gmock.h"

namespace perfetto {
namespace base {
namespace {

using ::testing::_;
using ::testing::Return;

template <typename T>
class MockFuturePollable : public FuturePollable<T> {
 public:
  MOCK_METHOD1(Poll, FuturePollResult<T>(PollContext*));
};

template <typename T>
class MockStreamPollable : public StreamPollable<T> {
 public:
  MOCK_METHOD1(PollNext, StreamPollResult<T>(PollContext*));
};

TEST(SpawnUnittest, SpawnFuture) {
  base::TestTaskRunner task_runner;

  base::EventFd fd;
  auto pollable = std::make_unique<MockFuturePollable<int>>();
  EXPECT_CALL(*pollable, Poll(_))
      .WillOnce([&fd](PollContext* ctx) {
        fd.Clear();
        ctx->RegisterInterested(fd.fd());
        return PendingPollResult();
      })
      .WillOnce(Return(FuturePollResult<int>(1024)));
  auto res = SpawnResultFuture<int>(
      &task_runner,
      [pollable = std::make_shared<std::unique_ptr<MockFuturePollable<int>>>(
           std::move(pollable))]() mutable {
        return base::Future<int>(std::move(*pollable));
      });

  task_runner.RunUntilIdle();
  ASSERT_EQ(res.channel()->ReadNonBlocking().item, std::nullopt);

  task_runner.RunUntilIdle();
  ASSERT_EQ(res.channel()->ReadNonBlocking().item, std::nullopt);

  fd.Notify();
  task_runner.RunUntilIdle();

  auto read = res.channel()->ReadNonBlocking();
  ASSERT_EQ(read.item, 1024);
  ASSERT_TRUE(read.is_closed);

  read = res.channel()->ReadNonBlocking();
  ASSERT_TRUE(read.is_closed);
}

TEST(SpawnUnittest, SpawnStream) {
  base::TestTaskRunner task_runner;

  base::EventFd fd;
  auto pollable = std::make_unique<MockStreamPollable<int>>();
  EXPECT_CALL(*pollable, PollNext(_))
      .WillOnce([&fd](PollContext* ctx) {
        fd.Clear();
        ctx->RegisterInterested(fd.fd());
        return PendingPollResult();
      })
      .WillOnce(Return(StreamPollResult<int>(1024)))
      .WillOnce([&fd](PollContext* ctx) {
        fd.Clear();
        ctx->RegisterInterested(fd.fd());
        return PendingPollResult();
      })
      .WillOnce(Return(StreamPollResult<int>(2048)))
      .WillOnce(Return(DonePollResult()));
  auto res = SpawnResultStream<int>(
      &task_runner,
      [pollable = std::make_shared<std::unique_ptr<MockStreamPollable<int>>>(
           std::move(pollable))]() mutable {
        return base::Stream<int>(std::move(*pollable));
      });

  task_runner.RunUntilIdle();
  ASSERT_EQ(res.channel()->ReadNonBlocking().item, std::nullopt);

  fd.Notify();
  task_runner.RunUntilIdle();

  auto read = res.channel()->ReadNonBlocking();
  ASSERT_EQ(read.item, 1024);
  ASSERT_FALSE(read.is_closed);

  task_runner.RunUntilIdle();
  ASSERT_EQ(res.channel()->ReadNonBlocking().item, std::nullopt);

  fd.Notify();
  task_runner.RunUntilIdle();

  read = res.channel()->ReadNonBlocking();
  ASSERT_EQ(read.item, 2048);
  ASSERT_TRUE(read.is_closed);
}

}  // namespace
}  // namespace base
}  // namespace perfetto
