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

#import "ios/chrome/browser/drive_file_picker/test/drive_file_picker_app_interface.h"

#import <memory>

#import "base/apple/foundation_util.h"
#import "ios/chrome/browser/drive/model/drive_list.h"
#import "ios/chrome/browser/drive/model/drive_service_factory.h"
#import "ios/chrome/browser/drive/model/test_drive_list.h"
#import "ios/chrome/browser/drive/model/test_drive_service.h"
#import "ios/chrome/browser/shared/model/browser/browser.h"
#import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
#import "ios/chrome/browser/shared/public/commands/drive_file_picker_commands.h"
#import "ios/chrome/browser/web/model/choose_file/choose_file_tab_helper.h"
#import "ios/chrome/browser/web/model/choose_file/fake_choose_file_controller.h"
#import "ios/chrome/test/app/chrome_test_util.h"

@implementation DriveFilePickerAppInterface {
  // DriveListResult object which can be edited and will be passed to the
  // current DriveService when `-[DriveFilePickerAppInterface
  // endDriveListResult]` is called.
  std::unique_ptr<DriveListResult> _driveListResult;
}

+ (instancetype)sharedInstance {
  static DriveFilePickerAppInterface* instance =
      [[DriveFilePickerAppInterface alloc] init];
  return instance;
}

+ (void)startChoosingSingleFileInCurrentWebState {
  Browser* currentBrowser = chrome_test_util::GetCurrentBrowser();
  WebStateList* webStateList = currentBrowser->GetWebStateList();
  ChooseFileTabHelper* tab_helper =
      ChooseFileTabHelper::FromWebState(webStateList->GetActiveWebState());
  auto controller = std::make_unique<FakeChooseFileController>(
      ChooseFileEvent::Builder()
          .SetAllowMultipleFiles(false)
          .SetHasSelectedFile(false)
          .SetWebState(webStateList->GetActiveWebState())
          .Build());
  tab_helper->StartChoosingFiles(std::move(controller));
}

+ (void)startChoosingMultipleFilesInCurrentWebState {
  Browser* currentBrowser = chrome_test_util::GetCurrentBrowser();
  WebStateList* webStateList = currentBrowser->GetWebStateList();
  ChooseFileTabHelper* tab_helper =
      ChooseFileTabHelper::FromWebState(webStateList->GetActiveWebState());
  auto controller = std::make_unique<FakeChooseFileController>(
      ChooseFileEvent::Builder()
          .SetAllowMultipleFiles(true)
          .SetHasSelectedFile(false)
          .SetWebState(webStateList->GetActiveWebState())
          .Build());
  tab_helper->StartChoosingFiles(std::move(controller));
}

+ (void)beginDriveListResult {
  DriveFilePickerAppInterface* shared =
      [DriveFilePickerAppInterface sharedInstance];
  CHECK(!shared->_driveListResult);
  shared->_driveListResult = std::make_unique<DriveListResult>();
}

+ (void)addDriveItemWithIdentifier:(NSString*)identifier
                              name:(NSString*)name
                          isFolder:(BOOL)isFolder
                          mimeType:(NSString*)mimeType
                       canDownload:(BOOL)canDownload {
  DriveFilePickerAppInterface* shared =
      [DriveFilePickerAppInterface sharedInstance];
  CHECK(shared->_driveListResult);
  DriveItem newItem;
  newItem.identifier = [identifier copy];
  newItem.name = [name copy];
  newItem.is_folder = isFolder;
  newItem.mime_type = [mimeType copy];
  newItem.can_download = canDownload;
  shared->_driveListResult->items.push_back(newItem);
}

+ (void)endDriveListResult {
  DriveFilePickerAppInterface* shared =
      [DriveFilePickerAppInterface sharedInstance];
  CHECK(shared->_driveListResult);
  auto testDriveList = std::make_unique<TestDriveList>(nil);
  testDriveList->SetDriveListResult(*shared->_driveListResult);
  shared->_driveListResult.reset();
  ProfileIOS* currentProfile =
      chrome_test_util::GetCurrentBrowser()->GetProfile();
  drive::TestDriveService* driveService = static_cast<drive::TestDriveService*>(
      drive::DriveServiceFactory::GetForProfile(currentProfile));
  driveService->SetDriveList(std::move(testDriveList));
}

+ (void)showDriveFilePicker {
  id<DriveFilePickerCommands> handler =
      chrome_test_util::HandlerForActiveBrowser();
  [handler showDriveFilePicker];
}

+ (void)hideDriveFilePicker {
  id<DriveFilePickerCommands> handler =
      chrome_test_util::HandlerForActiveBrowser();
  [handler hideDriveFilePicker];
}
@end
