/*
 * Copyright (C) 2018 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/ipc/deferred.h"

#include "perfetto/base/logging.h"
#include "test/gtest_and_gmock.h"

#include "src/ipc/test/deferred_unittest_messages.pb.h"

namespace perfetto {
namespace ipc {
namespace {

#if PERFETTO_DCHECK_IS_ON()
#define EXPECT_DCHECK(x) EXPECT_DEATH_IF_SUPPORTED((x), ".*")
#else
#define EXPECT_DCHECK(x) x
#endif

TEST(DeferredTest, BindAndResolve) {
  Deferred<TestMessage> deferred;
  std::shared_ptr<int> num_callbacks(new int{0});
  deferred.Bind([num_callbacks](AsyncResult<TestMessage> msg) {
    ASSERT_TRUE(msg.success());
    ASSERT_TRUE(msg);
    ASSERT_EQ(42, msg->num());
    ASSERT_EQ(13, msg.fd());
    ASSERT_EQ("foo", msg->str());
    (*num_callbacks)++;
  });

  AsyncResult<TestMessage> res = AsyncResult<TestMessage>::Create();
  res->set_num(42);
  res.set_fd(13);
  (*res).set_str("foo");
  deferred.Resolve(std::move(res));

  // A second call to Resolve() or Reject() shouldn't have any effect beause we
  // didn't set has_more.
  EXPECT_DCHECK(deferred.Resolve(std::move(res)));
  EXPECT_DCHECK(deferred.Reject());

  ASSERT_EQ(1, *num_callbacks);
}

// In case of a Reject() a callback with a nullptr should be received.
TEST(DeferredTest, BindAndFail) {
  Deferred<TestMessage> deferred;
  std::shared_ptr<int> num_callbacks(new int{0});
  deferred.Bind([num_callbacks](AsyncResult<TestMessage> msg) {
    ASSERT_EQ(-1, msg.fd());
    ASSERT_FALSE(msg.success());
    ASSERT_FALSE(msg);
    ASSERT_EQ(nullptr, msg.operator->());
    (*num_callbacks)++;
  });

  AsyncResult<TestMessage> res = AsyncResult<TestMessage>::Create();
  res.set_fd(42);
  deferred.Reject();
  EXPECT_DCHECK(deferred.Resolve(std::move(res)));
  EXPECT_DCHECK(deferred.Reject());
  ASSERT_EQ(1, *num_callbacks);
}

// Test the RAII behavior.
TEST(DeferredTest, AutoRejectIfOutOfScope) {
  std::shared_ptr<int> num_callbacks(new int{0});
  {
    Deferred<TestMessage> deferred;
    deferred.Bind([num_callbacks](AsyncResult<TestMessage> msg) {
      ASSERT_FALSE(msg.success());
      (*num_callbacks)++;
    });
  }
  ASSERT_EQ(1, *num_callbacks);
}

// Binds two callbacks one after the other and tests that the bind state of the
// first callback is released.
TEST(DeferredTest, BindTwiceDoesNotHoldBindState) {
  // Use shared_ptr's use_count() to infer the bind state of the callback.
  std::shared_ptr<int> num_callbacks(new int{0});
  Deferred<TestMessage> deferred;
  deferred.Bind(
      [num_callbacks](AsyncResult<TestMessage>) { (*num_callbacks)++; });

  // At this point both the shared_ptr above and the callback in |deferred| are
  // refcounting the bind state.
  ASSERT_GE(num_callbacks.use_count(), 2);

  // Re-binding the callback should release the bind state, without invoking the
  // old callback.
  deferred.Bind([](AsyncResult<TestMessage>) {});
  ASSERT_EQ(1, num_callbacks.use_count());
  ASSERT_EQ(0, *num_callbacks);

  // Test that the new callback is invoked when re-bindings.
  deferred.Bind([num_callbacks](AsyncResult<TestMessage> msg) {
    ASSERT_TRUE(msg.success());
    ASSERT_EQ(4242, msg->num());
    (*num_callbacks)++;
  });
  AsyncResult<TestMessage> res = AsyncResult<TestMessage>::Create();
  res->set_num(4242);
  deferred.Resolve(std::move(res));
  ASSERT_EQ(1, *num_callbacks);
  ASSERT_EQ(1, num_callbacks.use_count());
}

TEST(DeferredTest, MoveOperators) {
  Deferred<TestMessage> deferred;
  std::shared_ptr<int> num_callbacks(new int{0});
  std::function<void(AsyncResult<TestMessage>)> callback =
      [num_callbacks](AsyncResult<TestMessage> msg) {
        ASSERT_TRUE(msg.success());
        ASSERT_GE(msg->num(), 42);
        ASSERT_LE(msg->num(), 43);
        ASSERT_EQ(msg->num() * 10, msg.fd());
        ASSERT_EQ(std::to_string(msg->num()), msg->str());
        (*num_callbacks)++;
      };
  deferred.Bind(callback);

  // Do a bit of std::move() dance with both the Deferred and the AsyncResult.
  AsyncResult<TestMessage> res = AsyncResult<TestMessage>::Create();
  res.set_fd(420);
  res->set_num(42);
  AsyncResult<TestMessage> res_moved(std::move(res));
  res = std::move(res_moved);
  res->set_str("42");
  res_moved = std::move(res);

  Deferred<TestMessage> deferred_moved(std::move(deferred));
  deferred = std::move(deferred_moved);
  deferred_moved = std::move(deferred);

  EXPECT_DCHECK(deferred.Reject());  // |deferred| has been cleared.
  ASSERT_EQ(0, *num_callbacks);

  deferred_moved.Resolve(std::move(res_moved));  // This, instead, should fire.
  ASSERT_EQ(1, *num_callbacks);

  // |deferred| and |res| have lost their state but should remain reusable.
  deferred.Bind(callback);
  res = AsyncResult<TestMessage>::Create();
  res.set_fd(430);
  res->set_num(43);
  res->set_str("43");
  deferred.Resolve(std::move(res));
  ASSERT_EQ(2, *num_callbacks);

  // Finally re-bind |deferred|, move it to a new scoped Deferred and verify
  // that the moved-into object still auto-nacks the callback.
  deferred.Bind([num_callbacks](AsyncResult<TestMessage> msg) {
    ASSERT_FALSE(msg.success());
    (*num_callbacks)++;
  });
  { Deferred<TestMessage> scoped_deferred(std::move(deferred)); }
  ASSERT_EQ(3, *num_callbacks);
  callback = nullptr;
  ASSERT_EQ(1, num_callbacks.use_count());
}

// Covers the case of a streaming reply, where the deferred keeps being resolved
// until has_more == true.
TEST(DeferredTest, StreamingReply) {
  Deferred<TestMessage> deferred;
  std::shared_ptr<int> num_callbacks(new int{0});
  std::function<void(AsyncResult<TestMessage>)> callback =
      [num_callbacks](AsyncResult<TestMessage> msg) {
        ASSERT_TRUE(msg.success());
        ASSERT_EQ(*num_callbacks == 0 ? 13 : -1, msg.fd());
        ASSERT_EQ(*num_callbacks, msg->num());
        ASSERT_EQ(std::to_string(*num_callbacks), msg->str());
        ASSERT_EQ(msg->num() < 3, msg.has_more());
        (*num_callbacks)++;
      };
  deferred.Bind(callback);

  for (int i = 0; i < 3; i++) {
    AsyncResult<TestMessage> res = AsyncResult<TestMessage>::Create();
    res.set_fd(i == 0 ? 13 : -1);
    res->set_num(i);
    res->set_str(std::to_string(i));
    res.set_has_more(true);
    AsyncResult<TestMessage> res_moved(std::move(res));
    deferred.Resolve(std::move(res_moved));
  }

  Deferred<TestMessage> deferred_moved(std::move(deferred));
  AsyncResult<TestMessage> res = AsyncResult<TestMessage>::Create();
  res->set_num(3);
  res->set_str(std::to_string(3));
  res.set_has_more(false);
  deferred_moved.Resolve(std::move(res));
  ASSERT_EQ(4, *num_callbacks);

  EXPECT_DCHECK(deferred_moved.Reject());
  ASSERT_EQ(4, *num_callbacks);
  callback = nullptr;
  ASSERT_EQ(1, num_callbacks.use_count());
}

// Similar to the above, but checks that destroying a Deferred without having
// resolved with has_more == true automatically rejects once out of scope.
TEST(DeferredTest, StreamingReplyIsRejectedOutOfScope) {
  std::shared_ptr<int> num_callbacks(new int{0});

  {
    Deferred<TestMessage> deferred;
    deferred.Bind([num_callbacks](AsyncResult<TestMessage> msg) {
      ASSERT_EQ((*num_callbacks) < 3, msg.success());
      ASSERT_EQ(msg.success(), msg.has_more());
      (*num_callbacks)++;
    });

    for (int i = 0; i < 3; i++) {
      AsyncResult<TestMessage> res = AsyncResult<TestMessage>::Create();
      res.set_has_more(true);
      deferred.Resolve(std::move(res));
    }

    // |deferred_moved| going out of scope should cause a Reject().
    { Deferred<TestMessage> deferred_moved = std::move(deferred); }
    ASSERT_EQ(4, *num_callbacks);
  }

  // |deferred| going out of scope should do noting, it has been std::move()'d.
  ASSERT_EQ(4, *num_callbacks);
  ASSERT_EQ(1, num_callbacks.use_count());
}

// Tests that a Deferred<Specialized> still behaves sanely after it has been
// moved into a DeferredBase.
TEST(DeferredTest, MoveAsBase) {
  Deferred<TestMessage> deferred;
  std::shared_ptr<int> num_callbacks(new int{0});
  deferred.Bind([num_callbacks](AsyncResult<TestMessage> msg) {
    ASSERT_TRUE(msg.success());
    ASSERT_EQ(13, msg.fd());
    ASSERT_EQ(42, msg->num());
    ASSERT_EQ("foo", msg->str());
    (*num_callbacks)++;
  });

  DeferredBase deferred_base(std::move(deferred));
  ASSERT_FALSE(deferred.IsBound());
  ASSERT_TRUE(deferred_base.IsBound());

  std::unique_ptr<TestMessage> msg(new TestMessage());
  msg->set_num(42);
  msg->set_str("foo");

  AsyncResult<ProtoMessage> async_result_base(std::move(msg));
  async_result_base.set_fd(13);
  deferred_base.Resolve(std::move(async_result_base));

  EXPECT_DCHECK(deferred_base.Resolve(std::move(async_result_base)));
  EXPECT_DCHECK(deferred_base.Reject());

  ASSERT_EQ(1, *num_callbacks);
}

}  // namespace
}  // namespace ipc
}  // namespace perfetto
