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

#import "ios/chrome/browser/translate/translate_infobar_delegate_observer_bridge.h"

#include <memory>

#include "components/language/core/browser/language_model.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/translate/core/browser/mock_translate_client.h"
#include "components/translate/core/browser/mock_translate_driver.h"
#include "components/translate/core/browser/mock_translate_ranker.h"
#include "components/translate/core/browser/translate_infobar_delegate.h"
#include "components/translate/core/browser/translate_manager.h"
#include "components/translate/core/browser/translate_pref_names.h"
#include "components/translate/core/browser/translate_prefs.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

using testing::_;
using translate::testing::MockTranslateClient;
using translate::testing::MockTranslateDriver;
using translate::testing::MockTranslateRanker;

class MockLanguageModel : public language::LanguageModel {
  std::vector<LanguageDetails> GetLanguages() override {
    return {LanguageDetails("en", 1.0)};
  }
};

class MockTranslateInfoBarDelegate
    : public translate::TranslateInfoBarDelegate {
 public:
  MockTranslateInfoBarDelegate(
      const base::WeakPtr<translate::TranslateManager>& translate_manager,
      bool is_off_the_record,
      translate::TranslateStep step,
      const std::string& original_language,
      const std::string& target_language,
      translate::TranslateErrors::Type error_type,
      bool triggered_from_menu)
      : translate::TranslateInfoBarDelegate(translate_manager,
                                            is_off_the_record,
                                            step,
                                            original_language,
                                            target_language,
                                            error_type,
                                            triggered_from_menu) {}
  ~MockTranslateInfoBarDelegate() override {}

  MOCK_METHOD1(SetObserver, void(Observer* observer));
};

class MockTranslateInfoBarDelegateFactory {
 public:
  MockTranslateInfoBarDelegateFactory() {
    pref_service_ =
        std::make_unique<sync_preferences::TestingPrefServiceSyncable>();
    translate::TranslatePrefs::RegisterProfilePrefs(pref_service_->registry());
    pref_service_->registry()->RegisterBooleanPref(
        prefs::kOfferTranslateEnabled, true);
    client_ =
        std::make_unique<MockTranslateClient>(&driver_, pref_service_.get());
    ranker_ = std::make_unique<MockTranslateRanker>();
    language_model_ = std::make_unique<MockLanguageModel>();
    manager_ = std::make_unique<translate::TranslateManager>(
        client_.get(), ranker_.get(), language_model_.get());
    delegate_ = std::make_unique<MockTranslateInfoBarDelegate>(
        manager_->GetWeakPtr(), false,
        translate::TranslateStep::TRANSLATE_STEP_BEFORE_TRANSLATE, "fr", "en",
        translate::TranslateErrors::Type::NONE, false);
  }

  ~MockTranslateInfoBarDelegateFactory() = default;

  MockTranslateInfoBarDelegate* GetMockTranslateInfoBarDelegate() {
    return delegate_.get();
  }

 private:
  MockTranslateDriver driver_;
  std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> pref_service_;
  std::unique_ptr<MockTranslateClient> client_;
  std::unique_ptr<MockTranslateRanker> ranker_;
  std::unique_ptr<MockLanguageModel> language_model_;
  std::unique_ptr<translate::TranslateManager> manager_;
  std::unique_ptr<MockTranslateInfoBarDelegate> delegate_;
};

@interface TestTranslateInfoBarDelegateObserver
    : NSObject <TranslateInfobarDelegateObserving>

@property(nonatomic) BOOL onTranslateStepChangedCalled;

@property(nonatomic) translate::TranslateStep translateStep;

@property(nonatomic) translate::TranslateErrors::Type errorType;

@property(nonatomic) BOOL onIsDeclinedByUserCalled;

@end

@implementation TestTranslateInfoBarDelegateObserver

#pragma mark - TranslateInfobarDelegateObserving

- (void)translateInfoBarDelegate:(translate::TranslateInfoBarDelegate*)delegate
          didChangeTranslateStep:(translate::TranslateStep)step
                   withErrorType:(translate::TranslateErrors::Type)errorType {
  self.onTranslateStepChangedCalled = YES;
  self.translateStep = step;
  self.errorType = errorType;
}

- (BOOL)translateInfoBarDelegateIsDeclinedByUser:
    (translate::TranslateInfoBarDelegate*)delegate {
  self.onIsDeclinedByUserCalled = YES;
  return YES;
}

@end

class TranslateInfobarDelegateObserverBridgeTest : public PlatformTest {
 protected:
  TranslateInfobarDelegateObserverBridgeTest()
      : observer_([[TestTranslateInfoBarDelegateObserver alloc] init]) {
    // Make sure the observer bridge sets up itself as an observer.
    EXPECT_CALL(*GetDelegate(), SetObserver(_)).Times(1);

    observer_bridge_ = std::make_unique<TranslateInfobarDelegateObserverBridge>(
        delegate_factory_.GetMockTranslateInfoBarDelegate(), observer_);
  }

  ~TranslateInfobarDelegateObserverBridgeTest() override {
    // Make sure the observer bridge removes itself as an observer.
    EXPECT_CALL(*GetDelegate(), SetObserver(nullptr)).Times(1);
  }

  MockTranslateInfoBarDelegate* GetDelegate() {
    return delegate_factory_.GetMockTranslateInfoBarDelegate();
  }

  translate::TranslateInfoBarDelegate::Observer* GetObserverBridge() {
    return observer_bridge_.get();
  }

  TestTranslateInfoBarDelegateObserver* GetDelegateObserver() {
    return observer_;
  }

 private:
  MockTranslateInfoBarDelegateFactory delegate_factory_;
  TestTranslateInfoBarDelegateObserver* observer_;
  std::unique_ptr<TranslateInfobarDelegateObserverBridge> observer_bridge_;

  DISALLOW_COPY_AND_ASSIGN(TranslateInfobarDelegateObserverBridgeTest);
};

// Tests that |OnTranslateStepChanged| call is forwarded by the observer bridge.
TEST_F(TranslateInfobarDelegateObserverBridgeTest, OnTranslateStepChanged) {
  ASSERT_FALSE(GetDelegateObserver().onTranslateStepChangedCalled);
  GetObserverBridge()->OnTranslateStepChanged(
      translate::TranslateStep::TRANSLATE_STEP_TRANSLATE_ERROR,
      translate::TranslateErrors::Type::BAD_ORIGIN);
  EXPECT_TRUE(GetDelegateObserver().onTranslateStepChangedCalled);
  EXPECT_EQ(GetDelegateObserver().translateStep,
            translate::TranslateStep::TRANSLATE_STEP_TRANSLATE_ERROR);
  EXPECT_EQ(GetDelegateObserver().errorType,
            translate::TranslateErrors::Type::BAD_ORIGIN);
}

// Tests that |IsDeclinedByUser| call is forwarded by the observer bridge.
TEST_F(TranslateInfobarDelegateObserverBridgeTest, IsDeclinedByUser) {
  ASSERT_FALSE(GetDelegateObserver().onIsDeclinedByUserCalled);
  GetObserverBridge()->IsDeclinedByUser();
  EXPECT_TRUE(GetDelegateObserver().onIsDeclinedByUserCalled);
}
