// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "missive/util/status_macros.h"

#include <memory>
#include <stdio.h>
#include <utility>

#include <base/bind.h>
#include <base/callback.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "missive/util/status.h"
#include "missive/util/statusor.h"

namespace reporting {
namespace {

Status StatusTestFunction(bool fail) {
  if (fail) {
    return Status(error::INVALID_ARGUMENT, "Fail was true.");
  }
  return Status::StatusOK();
}

Status ReturnIfErrorWrapperFunction(bool fail) {
  RETURN_IF_ERROR(StatusTestFunction(fail));

  // Return error here to make sure that we aren't just returning the OK from
  // StatusTestFunction.
  return Status(error::INTERNAL, "Returning Internal Error");
}

// RETURN_IF_ERROR macro actually returns on a non-OK status.
TEST(StatusMacros, ReturnsOnError) {
  Status test_status = ReturnIfErrorWrapperFunction(/*fail=*/true);
  EXPECT_FALSE(test_status.ok());
  EXPECT_EQ(test_status.code(), error::INVALID_ARGUMENT);
}

// RETURN_IF_ERROR macro continues on an OK status.
TEST(StatusMacros, ReturnIfErrorContinuesOnOk) {
  Status test_status = ReturnIfErrorWrapperFunction(/*fail=*/false);
  EXPECT_FALSE(test_status.ok());
  EXPECT_EQ(test_status.code(), error::INTERNAL);
}

// Function to test StatusOr macros.
template <typename T>
StatusOr<T> StatusOrTestFunction(bool fail, T return_value) {
  if (fail) {
    return Status(error::INVALID_ARGUMENT, "Test failure requested.");
  }
  return std::forward<T>(return_value);
}

// Function for testing ASSIGN_OR_RETURN.
template <typename T>
StatusOr<T> AssignOrReturnWrapperFunction(bool fail, T return_value) {
  ASSIGN_OR_RETURN(T value,
                   StatusOrTestFunction(fail, std::forward<T>(return_value)));
  return std::forward<T>(value);
}

// ASSIGN_OR_RETURN actually assigns the value if the status is OK.
TEST(StatusMacros, AssignOnOk) {
  constexpr int kReturnValue = 42;

  StatusOr<int> status_or_result =
      AssignOrReturnWrapperFunction(/*fail=*/false, kReturnValue);

  ASSERT_TRUE(status_or_result.ok());
  EXPECT_EQ(status_or_result.ValueOrDie(), kReturnValue);
}

// ASSIGN_OR_RETURN actually returns on a non-OK status.
TEST(StatusMacros, ReturnOnError) {
  StatusOr<int> status_or_result =
      AssignOrReturnWrapperFunction(/*fail=*/true, /*return_value=*/0);
  EXPECT_FALSE(status_or_result.ok());
}

StatusOr<int> MultipleAssignOrReturnWrapperFunction(int return_value) {
  bool fail = false;
  int value;
  ASSIGN_OR_RETURN(value, StatusOrTestFunction(fail, return_value));
  ASSIGN_OR_RETURN(value, StatusOrTestFunction(fail, return_value));
  ASSIGN_OR_RETURN(value, StatusOrTestFunction(fail, return_value));
  ASSIGN_OR_RETURN(value, StatusOrTestFunction(fail, return_value));
  return value;
}

// ASSIGN_OR_RETURN compiles when used multiple times.
TEST(StatusMacros, MultipleAssignsSucceed) {
  constexpr int kReturnValue = 42;
  StatusOr<int> status_or_result =
      MultipleAssignOrReturnWrapperFunction(kReturnValue);
  ASSERT_TRUE(status_or_result.ok());
  EXPECT_EQ(status_or_result.ValueOrDie(), kReturnValue);
}

// ASSIGN_OR_RETURN actually moves the value if the status is OK.
TEST(StatusMacros, AssignOnOkMoveable) {
  constexpr int kReturnValue = 42;

  StatusOr<std::unique_ptr<int>> status_or_result =
      AssignOrReturnWrapperFunction(/*fail=*/false,
                                    std::make_unique<int>(kReturnValue));

  ASSERT_TRUE(status_or_result.ok());
  EXPECT_EQ(*status_or_result.ValueOrDie(), kReturnValue);
}

// ASSIGN_OR_RETURN actually returns on a non-OK status.
TEST(StatusMacros, ReturnOnErrorMoveable) {
  StatusOr<std::unique_ptr<int>> status_or_result =
      AssignOrReturnWrapperFunction(/*fail=*/true,
                                    std::make_unique<int>(/*return_value=*/0));
  EXPECT_FALSE(status_or_result.ok());
}

// ASSIGN_OR_ONCE_CALLBACK_AND_RETURN testing
void AssignOrOnceCallbackWrapperFunction(
    bool fail, base::OnceCallback<void(Status)> callback) {
  constexpr int kReturnValue = 42;
  int value;
  ASSIGN_OR_ONCE_CALLBACK_AND_RETURN(value, callback,
                                     StatusOrTestFunction(fail, kReturnValue));
  ASSERT_EQ(value, kReturnValue);
}

class CallbackTestClass {
 public:
  explicit CallbackTestClass(Status test_status) : test_status_(test_status) {}

  void AssignInCallback(Status status) {
    num_callback_invocations_++;
    test_status_ = status;
  }

  int num_callback_invocations() { return num_callback_invocations_; }
  Status status() { return test_status_; }

 private:
  Status test_status_;
  int num_callback_invocations_ = 0;
};

// ASSIGN_OR_ONCE_CALLBACK_AND_RETURN assigns on OK error.
TEST(StatusMacros, OnceCallbackAssignOnOk) {
  CallbackTestClass callback_test_class(Status::StatusOK());

  base::OnceCallback<void(Status)> callback =
      base::BindOnce(&CallbackTestClass::AssignInCallback,
                     base::Unretained(&callback_test_class));

  AssignOrOnceCallbackWrapperFunction(/*fail=*/false, std::move(callback));

  constexpr int kExpectedNumberOfCallbackInvocations = 0;
  EXPECT_EQ(callback_test_class.num_callback_invocations(),
            kExpectedNumberOfCallbackInvocations);
  EXPECT_EQ(callback_test_class.status(), Status::StatusOK());
}

// ASSIGN_OR_ONCE_CALLBACK_AND_RETURN calls the callback and returns on non-OK
// status.
TEST(StatusMacros, OnceCallbackAndReturnOnError) {
  CallbackTestClass callback_test_class(Status::StatusOK());

  base::OnceCallback<void(Status)> callback =
      base::BindOnce(&CallbackTestClass::AssignInCallback,
                     base::Unretained(&callback_test_class));

  AssignOrOnceCallbackWrapperFunction(/*fail=*/true, std::move(callback));

  constexpr int kExpectedNumberOfCallbackInvocations = 1;
  EXPECT_EQ(callback_test_class.num_callback_invocations(),
            kExpectedNumberOfCallbackInvocations);
  EXPECT_EQ(callback_test_class.status().code(), error::INVALID_ARGUMENT);
}

void MultipleAssignOrOnceCallbackWrapperFunction(
    base::OnceCallback<void(Status)> callback) {
  constexpr int kReturnValue = 42;
  constexpr bool kFail = false;

  int value;
  ASSIGN_OR_ONCE_CALLBACK_AND_RETURN(value, callback,
                                     StatusOrTestFunction(kFail, kReturnValue));
  ASSIGN_OR_ONCE_CALLBACK_AND_RETURN(value, callback,
                                     StatusOrTestFunction(kFail, kReturnValue));
  ASSIGN_OR_ONCE_CALLBACK_AND_RETURN(value, callback,
                                     StatusOrTestFunction(kFail, kReturnValue));
  ASSERT_EQ(value, kReturnValue);
}

// ASSIGN_OR_ONCE_CALLBACK_AND_RETURN can be used multiple times in a function.
TEST(StatusMacros, MultipleAssignOrOnceCallbackCompletes) {
  CallbackTestClass callback_test_class(Status::StatusOK());

  base::OnceCallback<void(Status)> callback =
      base::BindOnce(&CallbackTestClass::AssignInCallback,
                     base::Unretained(&callback_test_class));

  MultipleAssignOrOnceCallbackWrapperFunction(std::move(callback));

  constexpr int kExpectedNumberOfCallbackInvocations = 0;
  EXPECT_EQ(callback_test_class.num_callback_invocations(),
            kExpectedNumberOfCallbackInvocations);
  EXPECT_EQ(callback_test_class.status(), Status::StatusOK());
}

}  // namespace
}  // namespace reporting
