// Copyright 2013 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.

#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
#include "chrome/browser/extensions/api/image_writer_private/operation.h"
#include "chrome/browser/extensions/api/image_writer_private/operation_manager.h"
#include "chrome/browser/extensions/api/image_writer_private/test_utils.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/zlib/google/zip.h"

namespace extensions {
namespace image_writer {

namespace {

using testing::_;
using testing::AnyNumber;
using testing::AtLeast;
using testing::Gt;
using testing::Lt;

#if !defined(OS_CHROMEOS)

void SetUpUtilityClientProgressOnVerifyWrite(
    const std::vector<int>& progress_list,
    bool will_succeed,
    FakeImageWriterClient* client) {
  client->SimulateProgressOnVerifyWrite(progress_list, will_succeed);
}

#endif  // !defined(OS_CHROMEOS)

}  // namespace

// This class gives us a generic Operation with the ability to set or inspect
// the current path to the image file.
class OperationForTest : public Operation {
 public:
  OperationForTest(base::WeakPtr<OperationManager> manager_,
                   const ExtensionId& extension_id,
                   const std::string& device_path,
                   const base::FilePath& download_path)
      : Operation(manager_, extension_id, device_path, download_path) {}

  void StartImpl() override {}

  // Expose internal stages for testing.
  // Also wraps Operation's methods to run on correct sequence.
  void Unzip(const base::Closure& continuation) {
    PostTask(base::BindOnce(&Operation::Unzip, this, continuation));
  }

  void Write(const base::Closure& continuation) {
    PostTask(base::BindOnce(&Operation::Write, this, continuation));
  }

  void VerifyWrite(const base::Closure& continuation) {
    PostTask(base::BindOnce(&Operation::VerifyWrite, this, continuation));
  }

  void Start() { PostTask(base::BindOnce(&Operation::Start, this)); }

  void Cancel() { PostTask(base::BindOnce(&Operation::Cancel, this)); }

  // Helpers to set-up state for intermediate stages.
  void SetImagePath(const base::FilePath image_path) {
    image_path_ = image_path;
  }

  base::FilePath GetImagePath() { return image_path_; }

 private:
  ~OperationForTest() override {}
};

class ImageWriterOperationTest : public ImageWriterUnitTestBase {
 protected:
  ImageWriterOperationTest()
      : profile_(new TestingProfile), manager_(profile_.get()) {}
  void SetUp() override {
    ImageWriterUnitTestBase::SetUp();

    // Create the zip file.
    base::FilePath image_dir = test_utils_.GetTempDir().AppendASCII("zip");
    ASSERT_TRUE(base::CreateDirectory(image_dir));
    ASSERT_TRUE(base::CreateTemporaryFileInDir(image_dir, &image_path_));

    test_utils_.FillFile(image_path_, kImagePattern, kTestFileSize);

    zip_file_ = test_utils_.GetTempDir().AppendASCII("test_image.zip");
    ASSERT_TRUE(zip::Zip(image_dir, zip_file_, true));

    // Operation setup.
    operation_ =
        new OperationForTest(manager_.AsWeakPtr(),
                             kDummyExtensionId,
                             test_utils_.GetDevicePath().AsUTF8Unsafe(),
                             base::FilePath(FILE_PATH_LITERAL("/var/tmp")));
    operation_->SetImagePath(test_utils_.GetImagePath());
  }

  void TearDown() override {
    // Ensure all callbacks have been destroyed and cleanup occurs.

    // Cancel() will ensure we Shutdown() FakeImageWriterClient.
    operation_->Cancel();
    scoped_task_environment_.RunUntilIdle();

    ImageWriterUnitTestBase::TearDown();
  }

  base::FilePath image_path_;
  base::FilePath zip_file_;

  std::unique_ptr<TestingProfile> profile_;

  MockOperationManager manager_;
  scoped_refptr<OperationForTest> operation_;
};

// Unizpping a non-zip should do nothing.
TEST_F(ImageWriterOperationTest, UnzipNonZipFile) {
  EXPECT_CALL(manager_, OnProgress(kDummyExtensionId, _, _)).Times(0);

  EXPECT_CALL(manager_, OnError(kDummyExtensionId, _, _, _)).Times(0);
  EXPECT_CALL(manager_, OnProgress(kDummyExtensionId, _, _)).Times(0);
  EXPECT_CALL(manager_, OnComplete(kDummyExtensionId)).Times(0);

  operation_->Start();
  base::RunLoop run_loop;
  operation_->Unzip(run_loop.QuitClosure());
  run_loop.Run();
}

TEST_F(ImageWriterOperationTest, UnzipZipFile) {
  EXPECT_CALL(manager_, OnError(kDummyExtensionId, _, _, _)).Times(0);
  EXPECT_CALL(manager_,
              OnProgress(kDummyExtensionId, image_writer_api::STAGE_UNZIP, _))
      .Times(AtLeast(1));
  EXPECT_CALL(manager_,
              OnProgress(kDummyExtensionId, image_writer_api::STAGE_UNZIP, 0))
      .Times(AtLeast(1));
  EXPECT_CALL(manager_,
              OnProgress(kDummyExtensionId, image_writer_api::STAGE_UNZIP, 100))
      .Times(AtLeast(1));

  operation_->SetImagePath(zip_file_);

  operation_->Start();
  base::RunLoop run_loop;
  operation_->Unzip(run_loop.QuitClosure());
  run_loop.Run();

  EXPECT_TRUE(base::ContentsEqual(image_path_, operation_->GetImagePath()));
}

#if defined(OS_LINUX)
TEST_F(ImageWriterOperationTest, WriteImageToDevice) {
#if !defined(OS_CHROMEOS)
  auto set_up_utility_client_progress =
      [](const std::vector<int>& progress_list, bool will_succeed,
         FakeImageWriterClient* client) {
        client->SimulateProgressOnWrite(progress_list, will_succeed);
      };
  // Sets up client for simulating Operation::Progress() on Operation::Write.
  std::vector<int> progress_list{0, kTestFileSize / 2, kTestFileSize};
  test_utils_.RunOnUtilityClientCreation(base::BindOnce(
      set_up_utility_client_progress, progress_list, true /* will_succeed */));
#endif
  EXPECT_CALL(manager_, OnError(kDummyExtensionId, _, _, _)).Times(0);
  EXPECT_CALL(manager_,
              OnProgress(kDummyExtensionId, image_writer_api::STAGE_WRITE, _))
      .Times(AtLeast(1));
  EXPECT_CALL(manager_,
              OnProgress(kDummyExtensionId, image_writer_api::STAGE_WRITE, 0))
      .Times(AtLeast(1));
  EXPECT_CALL(manager_,
              OnProgress(kDummyExtensionId, image_writer_api::STAGE_WRITE, 100))
      .Times(AtLeast(1));

  operation_->Start();
  base::RunLoop run_loop;
  operation_->Write(run_loop.QuitClosure());
  run_loop.Run();
}
#endif  // defined(OS_LINUX)

#if !defined(OS_CHROMEOS)
// Chrome OS doesn't support verification in the ImageBurner, so these two tests
// are skipped.

TEST_F(ImageWriterOperationTest, VerifyFileSuccess) {
  // Sets up client for simulating Operation::Progress() on
  // Operation::VerifyWrite.
  std::vector<int> progress_list{0, kTestFileSize / 2, kTestFileSize};
  test_utils_.RunOnUtilityClientCreation(
      base::BindOnce(&SetUpUtilityClientProgressOnVerifyWrite, progress_list,
                     true /* will_succeed */));
  EXPECT_CALL(manager_, OnError(kDummyExtensionId, _, _, _)).Times(0);
  EXPECT_CALL(
      manager_,
      OnProgress(kDummyExtensionId, image_writer_api::STAGE_VERIFYWRITE, _))
      .Times(AtLeast(1));
  EXPECT_CALL(
      manager_,
      OnProgress(kDummyExtensionId, image_writer_api::STAGE_VERIFYWRITE, 0))
      .Times(AtLeast(1));
  EXPECT_CALL(
      manager_,
      OnProgress(kDummyExtensionId, image_writer_api::STAGE_VERIFYWRITE, 100))
      .Times(AtLeast(1));

  test_utils_.FillFile(
      test_utils_.GetDevicePath(), kImagePattern, kTestFileSize);

  operation_->Start();
  base::RunLoop run_loop;
  operation_->VerifyWrite(run_loop.QuitClosure());
  run_loop.Run();
}

TEST_F(ImageWriterOperationTest, VerifyFileFailure) {
  // Sets up client for simulating Operation::Progress() on
  // Operation::VerifyWrite. Also simulates failure.
  std::vector<int> progress_list{0, kTestFileSize / 2};
  test_utils_.RunOnUtilityClientCreation(
      base::BindOnce(&SetUpUtilityClientProgressOnVerifyWrite, progress_list,
                     false /* will_succeed */));
  EXPECT_CALL(
      manager_,
      OnProgress(kDummyExtensionId, image_writer_api::STAGE_VERIFYWRITE, _))
      .Times(AnyNumber());
  EXPECT_CALL(
      manager_,
      OnProgress(kDummyExtensionId, image_writer_api::STAGE_VERIFYWRITE, 100))
      .Times(0);
  EXPECT_CALL(manager_, OnComplete(kDummyExtensionId)).Times(0);
  EXPECT_CALL(
      manager_,
      OnError(kDummyExtensionId, image_writer_api::STAGE_VERIFYWRITE, _, _))
      .Times(1);

  test_utils_.FillFile(
      test_utils_.GetDevicePath(), kDevicePattern, kTestFileSize);

  operation_->Start();
  operation_->VerifyWrite(base::Bind(&base::DoNothing));
  content::RunAllBlockingPoolTasksUntilIdle();
}
#endif  // !defined(OS_CHROMEOS)

// Tests that on creation the operation_ has the expected state.
TEST_F(ImageWriterOperationTest, Creation) {
  EXPECT_EQ(0, operation_->GetProgress());
  EXPECT_EQ(image_writer_api::STAGE_UNKNOWN, operation_->GetStage());
}

}  // namespace image_writer
}  // namespace extensions
