// Copyright 2018 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 "shill/result_aggregator.h"

#include <base/bind.h>
#include <base/memory/ref_counted.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "shill/mock_event_dispatcher.h"
#include "shill/test_event_dispatcher.h"
#include "shill/testing.h"

namespace shill {

using base::Bind;
using base::Unretained;
using testing::_;
using testing::StrictMock;

namespace {

const int kTimeoutMilliseconds = 0;

}  // namespace

class ResultAggregatorTest : public ::testing::Test {
 public:
  ResultAggregatorTest()
      : aggregator_(new ResultAggregator(
            Bind(&ResultAggregatorTest::ReportResult, Unretained(this)))) {}
  ~ResultAggregatorTest() override = default;

  void TearDown() override {
    aggregator_ = nullptr;  // Ensure ReportResult is invoked before our dtor.
  }

  MOCK_METHOD(void, ReportResult, (const Error&));

 protected:
  scoped_refptr<ResultAggregator> aggregator_;
};

class ResultAggregatorTestWithDispatcher : public ResultAggregatorTest {
 public:
  ResultAggregatorTestWithDispatcher() = default;
  ~ResultAggregatorTestWithDispatcher() override = default;

  void InitializeResultAggregatorWithTimeout() {
    aggregator_ = new ResultAggregator(
        Bind(&ResultAggregatorTest::ReportResult, Unretained(this)),
        &dispatcher_, kTimeoutMilliseconds);
  }

 protected:
  EventDispatcherForTest dispatcher_;
};

class ResultAggregatorTestWithMockDispatcher : public ResultAggregatorTest {
 public:
  ResultAggregatorTestWithMockDispatcher() = default;
  ~ResultAggregatorTestWithMockDispatcher() override = default;

 protected:
  StrictMock<MockEventDispatcher> dispatcher_;
};

class ResultGenerator {
 public:
  explicit ResultGenerator(const scoped_refptr<ResultAggregator>& aggregator)
      : aggregator_(aggregator) {}
  ResultGenerator(const ResultGenerator&) = delete;
  ResultGenerator& operator=(const ResultGenerator&) = delete;

  ~ResultGenerator() = default;

  void GenerateResult(const Error::Type error_type) {
    aggregator_->ReportResult(Error(error_type));
  }

 private:
  scoped_refptr<ResultAggregator> aggregator_;
};

TEST_F(ResultAggregatorTestWithMockDispatcher, Unused) {
  EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kSuccess))).Times(0);
}

TEST_F(ResultAggregatorTestWithMockDispatcher, BothSucceed) {
  EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kSuccess)));
  ResultGenerator first_generator(aggregator_);
  ResultGenerator second_generator(aggregator_);
  first_generator.GenerateResult(Error::kSuccess);
  second_generator.GenerateResult(Error::kSuccess);
}

TEST_F(ResultAggregatorTestWithMockDispatcher, FirstFails) {
  EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)));
  ResultGenerator first_generator(aggregator_);
  ResultGenerator second_generator(aggregator_);
  first_generator.GenerateResult(Error::kOperationTimeout);
  second_generator.GenerateResult(Error::kSuccess);
}

TEST_F(ResultAggregatorTestWithMockDispatcher, SecondFails) {
  EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)));
  ResultGenerator first_generator(aggregator_);
  ResultGenerator second_generator(aggregator_);
  first_generator.GenerateResult(Error::kSuccess);
  second_generator.GenerateResult(Error::kOperationTimeout);
}

TEST_F(ResultAggregatorTestWithMockDispatcher, BothFail) {
  EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)));
  ResultGenerator first_generator(aggregator_);
  ResultGenerator second_generator(aggregator_);
  first_generator.GenerateResult(Error::kOperationTimeout);
  second_generator.GenerateResult(Error::kPermissionDenied);
}

TEST_F(ResultAggregatorTestWithMockDispatcher,
       TimeoutCallbackPostedOnConstruction) {
  EXPECT_CALL(dispatcher_, PostDelayedTask(_, _, kTimeoutMilliseconds));
  auto result_aggregator = base::MakeRefCounted<ResultAggregator>(
      Bind(&ResultAggregatorTest::ReportResult, Unretained(this)), &dispatcher_,
      kTimeoutMilliseconds);
}

TEST_F(ResultAggregatorTestWithDispatcher,
       TimeoutReceivedWithoutAnyResultsReceived) {
  InitializeResultAggregatorWithTimeout();
  EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)));
  ResultGenerator generator(aggregator_);
  dispatcher_.DispatchPendingEvents();  // Invoke timeout callback.
}

TEST_F(ResultAggregatorTestWithDispatcher, TimeoutAndOtherResultReceived) {
  // Timeout should override any other error results.
  InitializeResultAggregatorWithTimeout();
  EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)));
  ResultGenerator first_generator(aggregator_);
  ResultGenerator second_generator(aggregator_);
  first_generator.GenerateResult(Error::kSuccess);
  dispatcher_.DispatchPendingEvents();  // Invoke timeout callback.
  second_generator.GenerateResult(Error::kPermissionDenied);
}

TEST_F(ResultAggregatorTestWithDispatcher,
       TimeoutCallbackNotInvokedIfAllActionsComplete) {
  {
    auto result_aggregator = base::MakeRefCounted<ResultAggregator>(
        Bind(&ResultAggregatorTest::ReportResult, Unretained(this)),
        &dispatcher_, kTimeoutMilliseconds);
    // The result aggregator receives the one callback it expects, and goes
    // out of scope. At this point, it should invoke the ReportResult callback
    // with the error type kPermissionDenied that it copied.
    ResultGenerator generator(result_aggregator);
    generator.GenerateResult(Error::kPermissionDenied);
    EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kPermissionDenied)));
  }
  // The timeout callback should be canceled after the ResultAggregator went
  // out of scope and was destructed.
  EXPECT_CALL(*this, ReportResult(ErrorTypeIs(Error::kOperationTimeout)))
      .Times(0);
  dispatcher_.DispatchPendingEvents();
}

}  // namespace shill
