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

#include "chrome/browser/ash/scanner/scanner_keyed_service.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/constants/generative_ai_country_restrictions.h"
#include "base/check_deref.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_refptr.h"
#include "base/strings/string_view_util.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "components/drive/service/drive_api_service.h"
#include "components/drive/service/drive_service_interface.h"
#include "components/manta/manta_status.h"
#include "components/manta/proto/scanner.pb.h"
#include "components/manta/scanner_provider.h"
#include "components/signin/public/base/consent_level.h"
#include "components/signin/public/identity_manager/account_capabilities.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "content/public/browser/storage_partition.h"
#include "google_apis/common/auth_service.h"
#include "google_apis/common/request_sender.h"
#include "google_apis/drive/drive_api_url_generator.h"
#include "google_apis/gaia/core_account_id.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/traffic_annotation/network_traffic_annotation.h"

namespace {

constexpr auto kTrafficAnnotation =
    net::DefineNetworkTrafficAnnotation("chromeos_scanner", R"(
      semantics {
        sender: "ChromeOS Scanner"
        description:
          "Creates or mutates various Google entities - Docs, Sheets, "
          "Contacts, etc. - for the user. These operations are specified by "
          "responses from the Scanner service."
        trigger:
          "User selecting to create or mutate entities from the Scanner UI."
        internal {
          contacts {
            email: "e14s-eng@google.com"
          }
        }
        user_data {
          type: USER_CONTENT
        }
        data:
          "Files created by the Scanner service."
        destination: GOOGLE_OWNED_SERVICE
        last_reviewed: "2024-10-21"
      }
      policy {
        cookies_allowed: NO
        setting:
          "No setting. Users must take explicit action to trigger the feature."
        policy_exception_justification:
          "Not implemented, not considered useful. This request is part of a "
          "flow which is user-initiated."
      }
    )");

specialized_features::FeatureAccessConfig CreateFeatureAccessConfig() {
  specialized_features::FeatureAccessConfig config;
  config.settings_toggle_pref = ash::prefs::kScannerEnabled;
  config.disabled_in_kiosk_mode = true;
  config.consent_accepted_pref = ash::prefs::kScannerConsentDisclaimerAccepted;

  // Dogfood devices ignore all other checks.
  // On actual launch, we will be using the ScannerUpdate flag instead of
  // Dogfood which includes all extra checks.
  if (base::FeatureList::IsEnabled(ash::features::kScannerDogfood)) {
    return config;
  }

  config.feature_flag = &ash::features::kScannerUpdate;
  config.feature_management_flag = &ash::features::kFeatureManagementScanner;
  config.capability_callback =
      base::BindRepeating([](AccountCapabilities capabilities) {
        return capabilities.can_use_manta_service();
      });
  config.country_codes = ash::GetGenerativeAiCountryAllowlist();
  return config;
}

}  // namespace

ScannerKeyedService::ScannerKeyedService(
    PrefService* pref_service,
    signin::IdentityManager* identity_manager,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    std::unique_ptr<manta::ScannerProvider> scanner_provider,
    specialized_features::FeatureAccessChecker::VariationsServiceCallback
        variations_service_callback)
    : identity_manager_(identity_manager),
      access_checker_(CreateFeatureAccessConfig(),
                      /*prefs=*/pref_service,
                      /*identity_manager=*/identity_manager_,
                      std::move(variations_service_callback)),
      scanner_provider_(std::move(scanner_provider)) {
  if (identity_manager_ != nullptr) {
    scoped_refptr<base::SequencedTaskRunner> blocking_task_runner =
        base::ThreadPool::CreateSequencedTaskRunner(
            {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
             base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN});
    CoreAccountId account_id =
        identity_manager_->GetPrimaryAccountId(signin::ConsentLevel::kSignin);

    const GURL& base_url = GaiaUrls::GetInstance()->google_apis_origin_url();
    GURL base_thumbnail_url(
        google_apis::DriveApiUrlGenerator::kBaseThumbnailUrlForProduction);

    drive_service_ = std::make_unique<drive::DriveAPIService>(
        identity_manager_, url_loader_factory, blocking_task_runner.get(),
        base_url, base_thumbnail_url,
        /*custom_user_agent=*/"", kTrafficAnnotation);
    drive_service_->Initialize(account_id);

    auto auth_service = std::make_unique<google_apis::AuthService>(
        identity_manager_, account_id, url_loader_factory,
        std::vector<std::string>{GaiaConstants::kContactsOAuth2Scope});
    request_sender_ = std::make_unique<google_apis::RequestSender>(
        std::move(auth_service), url_loader_factory, blocking_task_runner,
        /*custom_user_agent=*/"", kTrafficAnnotation);
  }
}

ScannerKeyedService::~ScannerKeyedService() = default;

specialized_features::FeatureAccessFailureSet
ScannerKeyedService::CheckFeatureAccess() const {
  return access_checker_.Check();
}

void ScannerKeyedService::FetchActionsForImage(
    scoped_refptr<base::RefCountedMemory> jpeg_bytes,
    manta::ScannerProvider::ScannerProtoResponseCallback callback) {
  if (!scanner_provider_) {
    // `scanner_provider_` can only be nullptr when there is no identity
    // manager to instantiate the provider.
    std::move(callback).Run(
        nullptr,
        manta::MantaStatus(manta::MantaStatusCode::kNoIdentityManager));
    return;
  }
  manta::proto::ScannerInput scanner_input;
  scanner_input.set_image(std::string(base::as_string_view(*jpeg_bytes)));
  scanner_provider_->Call(scanner_input, std::move(callback));
}

void ScannerKeyedService::FetchActionDetailsForImage(
    scoped_refptr<base::RefCountedMemory> jpeg_bytes,
    manta::proto::ScannerAction selected_action,
    manta::ScannerProvider::ScannerProtoResponseCallback callback) {
  if (!scanner_provider_) {
    // `scanner_provider_` can only be nullptr when there is no identity
    // manager to instantiate the provider.
    std::move(callback).Run(
        nullptr,
        manta::MantaStatus(manta::MantaStatusCode::kNoIdentityManager));
    return;
  }
  manta::proto::ScannerInput scanner_input;
  scanner_input.set_image(std::string(base::as_string_view(*jpeg_bytes)));
  scanner_input.mutable_current_timestamp()->set_seconds(
      base::Time::Now().InSecondsFSinceUnixEpoch());
  *scanner_input.mutable_selected_action() = std::move(selected_action);
  scanner_provider_->Call(scanner_input, std::move(callback));
}

drive::DriveServiceInterface* ScannerKeyedService::GetDriveService() {
  return drive_service_.get();
}

google_apis::RequestSender* ScannerKeyedService::GetGoogleApisRequestSender() {
  return request_sender_.get();
}

void ScannerKeyedService::Shutdown() {}
