// Copyright 2018 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 "chrome/browser/web_applications/web_app_database.h"

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

#include "base/bind.h"
#include "base/callback.h"
#include "base/containers/contains.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h"
#include "chrome/browser/web_applications/proto/web_app.pb.h"
#include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h"
#include "chrome/browser/web_applications/system_web_apps/system_web_app_types.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_chromeos_data.h"
#include "chrome/browser/web_applications/web_app_database_factory.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_proto_utils.h"
#include "chrome/browser/web_applications/web_app_registry_update.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "components/services/app_service/public/cpp/file_handler.h"
#include "components/services/app_service/public/cpp/protocol_handler_info.h"
#include "components/services/app_service/public/cpp/share_target.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/time.h"
#include "components/sync/model/metadata_batch.h"
#include "components/sync/model/metadata_change_list.h"
#include "components/sync/model/model_error.h"
#include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/blink/public/mojom/manifest/capture_links.mojom.h"
#include "third_party/blink/public/mojom/manifest/handle_links.mojom.h"
#include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace web_app {

namespace {

ShareTarget_Method MethodToProto(apps::ShareTarget::Method method) {
  switch (method) {
    case apps::ShareTarget::Method::kGet:
      return ShareTarget_Method_GET;
    case apps::ShareTarget::Method::kPost:
      return ShareTarget_Method_POST;
  }
}

apps::ShareTarget::Method ProtoToMethod(ShareTarget_Method method) {
  switch (method) {
    case ShareTarget_Method_GET:
      return apps::ShareTarget::Method::kGet;
    case ShareTarget_Method_POST:
      return apps::ShareTarget::Method::kPost;
  }
}

ShareTarget_Enctype EnctypeToProto(apps::ShareTarget::Enctype enctype) {
  switch (enctype) {
    case apps::ShareTarget::Enctype::kFormUrlEncoded:
      return ShareTarget_Enctype_FORM_URL_ENCODED;
    case apps::ShareTarget::Enctype::kMultipartFormData:
      return ShareTarget_Enctype_MULTIPART_FORM_DATA;
  }
}

apps::ShareTarget::Enctype ProtoToEnctype(ShareTarget_Enctype enctype) {
  switch (enctype) {
    case ShareTarget_Enctype_FORM_URL_ENCODED:
      return apps::ShareTarget::Enctype::kFormUrlEncoded;
    case ShareTarget_Enctype_MULTIPART_FORM_DATA:
      return apps::ShareTarget::Enctype::kMultipartFormData;
  }
}

blink::mojom::CaptureLinks ProtoToCaptureLinks(
    WebAppProto::CaptureLinks capture_links) {
  switch (capture_links) {
    case WebAppProto_CaptureLinks_NONE:
      return blink::mojom::CaptureLinks::kNone;
    case WebAppProto_CaptureLinks_NEW_CLIENT:
      return blink::mojom::CaptureLinks::kNewClient;
    case WebAppProto_CaptureLinks_EXISTING_CLIENT_NAVIGATE:
      return blink::mojom::CaptureLinks::kExistingClientNavigate;
  }
}

WebAppProto::CaptureLinks CaptureLinksToProto(
    blink::mojom::CaptureLinks capture_links) {
  switch (capture_links) {
    case blink::mojom::CaptureLinks::kUndefined:
      NOTREACHED();
      [[fallthrough]];
    case blink::mojom::CaptureLinks::kNone:
      return WebAppProto_CaptureLinks_NONE;
    case blink::mojom::CaptureLinks::kNewClient:
      return WebAppProto_CaptureLinks_NEW_CLIENT;
    case blink::mojom::CaptureLinks::kExistingClientNavigate:
      return WebAppProto_CaptureLinks_EXISTING_CLIENT_NAVIGATE;
  }
}

blink::mojom::HandleLinks ProtoToHandleLinks(
    WebAppProto::HandleLinks handle_links) {
  switch (handle_links) {
    case WebAppProto_HandleLinks_AUTO:
      return blink::mojom::HandleLinks::kAuto;
    case WebAppProto_HandleLinks_PREFERRED:
      return blink::mojom::HandleLinks::kPreferred;
    case WebAppProto_HandleLinks_NOT_PREFERRED:
      return blink::mojom::HandleLinks::kNotPreferred;
  }
}

WebAppProto::HandleLinks HandleLinksToProto(
    blink::mojom::HandleLinks handle_links) {
  switch (handle_links) {
    case blink::mojom::HandleLinks::kUndefined:
      NOTREACHED();
      [[fallthrough]];
    case blink::mojom::HandleLinks::kAuto:
      return WebAppProto_HandleLinks_AUTO;
    case blink::mojom::HandleLinks::kPreferred:
      return WebAppProto_HandleLinks_PREFERRED;
    case blink::mojom::HandleLinks::kNotPreferred:
      return WebAppProto_HandleLinks_NOT_PREFERRED;
  }
}

LaunchHandler::RouteTo ProtoToLaunchHandlerRouteTo(
    const LaunchHandlerProto::RouteTo& route_to) {
  switch (route_to) {
    case LaunchHandlerProto_RouteTo_UNSPECIFIED_ROUTE:
    case LaunchHandlerProto_RouteTo_AUTO:
      return LaunchHandler::RouteTo::kAuto;
    case LaunchHandlerProto_RouteTo_NEW_CLIENT:
      return LaunchHandler::RouteTo::kNewClient;
    case LaunchHandlerProto_RouteTo_EXISTING_CLIENT:
      return LaunchHandler::RouteTo::kExistingClient;
  }
}

LaunchHandlerProto::RouteTo LaunchHandlerRouteToToProto(
    const LaunchHandler::RouteTo& route_to) {
  switch (route_to) {
    case LaunchHandler::RouteTo::kAuto:
      return LaunchHandlerProto_RouteTo_AUTO;
    case LaunchHandler::RouteTo::kNewClient:
      return LaunchHandlerProto_RouteTo_NEW_CLIENT;
    case LaunchHandler::RouteTo::kExistingClient:
      return LaunchHandlerProto_RouteTo_EXISTING_CLIENT;
  }
}

LaunchHandler::NavigateExistingClient
ProtoToLaunchHandlerNavigateExistingClient(
    const LaunchHandlerProto::NavigateExistingClient&
        navigate_existing_client) {
  switch (navigate_existing_client) {
    case LaunchHandlerProto_NavigateExistingClient_UNSPECIFIED_NAVIGATE:
    case LaunchHandlerProto_NavigateExistingClient_ALWAYS:
      return LaunchHandler::NavigateExistingClient::kAlways;
    case LaunchHandlerProto_NavigateExistingClient_NEVER:
      return LaunchHandler::NavigateExistingClient::kNever;
  }
}

LaunchHandlerProto::NavigateExistingClient
LaunchHandlerNavigateExistingClientToProto(
    const LaunchHandler::NavigateExistingClient& navigate_existing_client) {
  switch (navigate_existing_client) {
    case LaunchHandler::NavigateExistingClient::kAlways:
      return LaunchHandlerProto_NavigateExistingClient_ALWAYS;
    case LaunchHandler::NavigateExistingClient::kNever:
      return LaunchHandlerProto_NavigateExistingClient_NEVER;
  }
}

ApiApprovalState ProtoToApiApprovalState(
    WebAppProto::ApiApprovalState approval_state) {
  switch (approval_state) {
    case WebAppProto_ApiApprovalState_REQUIRES_PROMPT:
      return ApiApprovalState::kRequiresPrompt;
    case WebAppProto_ApiApprovalState_ALLOWED:
      return ApiApprovalState::kAllowed;
    case WebAppProto_ApiApprovalState_DISALLOWED:
      return ApiApprovalState::kDisallowed;
  }
}

WebAppProto::ApiApprovalState ApiApprovalStateToProto(
    ApiApprovalState approval_state) {
  switch (approval_state) {
    case ApiApprovalState::kRequiresPrompt:
      return WebAppProto_ApiApprovalState_REQUIRES_PROMPT;
    case ApiApprovalState::kAllowed:
      return WebAppProto_ApiApprovalState_ALLOWED;
    case ApiApprovalState::kDisallowed:
      return WebAppProto_ApiApprovalState_DISALLOWED;
  }
}

OsIntegrationState ProtoToOsIntegrationState(
    WebAppProto::OsIntegrationState state) {
  switch (state) {
    case WebAppProto_OsIntegrationState_ENABLED:
      return OsIntegrationState::kEnabled;
    case WebAppProto_OsIntegrationState_DISABLED:
      return OsIntegrationState::kDisabled;
  }
}

WebAppProto::OsIntegrationState OsIntegrationStateToProto(
    OsIntegrationState state) {
  switch (state) {
    case OsIntegrationState::kEnabled:
      return WebAppProto_OsIntegrationState_ENABLED;
    case OsIntegrationState::kDisabled:
      return WebAppProto_OsIntegrationState_DISABLED;
  }
}

}  // anonymous namespace

WebAppDatabase::WebAppDatabase(AbstractWebAppDatabaseFactory* database_factory,
                               ReportErrorCallback error_callback)
    : database_factory_(database_factory),
      error_callback_(std::move(error_callback)) {
  DCHECK(database_factory_);
}

WebAppDatabase::~WebAppDatabase() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

void WebAppDatabase::OpenDatabase(RegistryOpenedCallback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!store_);

  syncer::OnceModelTypeStoreFactory store_factory =
      database_factory_->GetStoreFactory();

  std::move(store_factory)
      .Run(syncer::WEB_APPS,
           base::BindOnce(&WebAppDatabase::OnDatabaseOpened,
                          weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

void WebAppDatabase::Write(
    const RegistryUpdateData& update_data,
    std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
    CompletionCallback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  CHECK(opened_);

  std::unique_ptr<syncer::ModelTypeStore::WriteBatch> write_batch =
      store_->CreateWriteBatch();

  // |update_data| can be empty here but we should write |metadata_change_list|
  // anyway.
  write_batch->TakeMetadataChangesFrom(std::move(metadata_change_list));

  for (const std::unique_ptr<WebApp>& web_app : update_data.apps_to_create) {
    auto proto = CreateWebAppProto(*web_app);
    write_batch->WriteData(web_app->app_id(), proto->SerializeAsString());
  }

  for (const std::unique_ptr<WebApp>& web_app : update_data.apps_to_update) {
    auto proto = CreateWebAppProto(*web_app);
    write_batch->WriteData(web_app->app_id(), proto->SerializeAsString());
  }

  for (const AppId& app_id : update_data.apps_to_delete)
    write_batch->DeleteData(app_id);

  store_->CommitWriteBatch(
      std::move(write_batch),
      base::BindOnce(&WebAppDatabase::OnDataWritten,
                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

// static
std::unique_ptr<WebAppProto> WebAppDatabase::CreateWebAppProto(
    const WebApp& web_app) {
  auto local_data = std::make_unique<WebAppProto>();

  // Required fields:
  const GURL start_url = web_app.start_url();
  DCHECK(!start_url.is_empty() && start_url.is_valid());

  DCHECK(!web_app.app_id().empty());

  // Set sync data to sync proto.
  *(local_data->mutable_sync_data()) = WebAppToSyncProto(web_app);

  local_data->set_name(web_app.name());

  DCHECK(web_app.sources_.any());
  local_data->mutable_sources()->set_system(web_app.sources_[Source::kSystem]);
  local_data->mutable_sources()->set_policy(web_app.sources_[Source::kPolicy]);
  local_data->mutable_sources()->set_web_app_store(
      web_app.sources_[Source::kWebAppStore]);
  local_data->mutable_sources()->set_sync(web_app.sources_[Source::kSync]);
  local_data->mutable_sources()->set_default_(
      web_app.sources_[Source::kDefault]);
  local_data->mutable_sources()->set_sub_app(web_app.sources_[Source::kSubApp]);

  local_data->set_is_locally_installed(web_app.is_locally_installed());

  // Optional fields:
  if (web_app.launch_query_params())
    local_data->set_launch_query_params(*web_app.launch_query_params());

  if (web_app.display_mode() != DisplayMode::kUndefined) {
    local_data->set_display_mode(
        ToWebAppProtoDisplayMode(web_app.display_mode()));
  }

  for (const DisplayMode& display_mode : web_app.display_mode_override()) {
    local_data->add_display_mode_override(
        ToWebAppProtoDisplayMode(display_mode));
  }

  local_data->set_description(web_app.description());
  if (!web_app.scope().is_empty())
    local_data->set_scope(web_app.scope().spec());
  if (web_app.theme_color().has_value())
    local_data->set_theme_color(web_app.theme_color().value());
  if (web_app.dark_mode_theme_color().has_value())
    local_data->set_dark_mode_theme_color(
        web_app.dark_mode_theme_color().value());
  if (web_app.background_color().has_value())
    local_data->set_background_color(web_app.background_color().value());
  if (web_app.dark_mode_background_color().has_value()) {
    local_data->set_dark_mode_background_color(
        web_app.dark_mode_background_color().value());
  }
  if (!web_app.last_badging_time().is_null()) {
    local_data->set_last_badging_time(
        syncer::TimeToProtoTime(web_app.last_badging_time()));
  }
  if (!web_app.last_launch_time().is_null()) {
    local_data->set_last_launch_time(
        syncer::TimeToProtoTime(web_app.last_launch_time()));
  }
  if (!web_app.install_time().is_null()) {
    local_data->set_install_time(
        syncer::TimeToProtoTime(web_app.install_time()));
  }
  if (!web_app.manifest_update_time().is_null()) {
    local_data->set_manifest_update_time(
        syncer::TimeToProtoTime(web_app.manifest_update_time()));
  }

  if (web_app.install_source_for_metrics()) {
    local_data->set_install_source_for_metrics(
        static_cast<int>(*web_app.install_source_for_metrics()));
  }

  if (web_app.chromeos_data().has_value()) {
    auto& chromeos_data = web_app.chromeos_data().value();
    auto* mutable_chromeos_data = local_data->mutable_chromeos_data();
    mutable_chromeos_data->set_show_in_launcher(chromeos_data.show_in_launcher);
    mutable_chromeos_data->set_show_in_search(chromeos_data.show_in_search);
    mutable_chromeos_data->set_show_in_management(
        chromeos_data.show_in_management);
    mutable_chromeos_data->set_is_disabled(chromeos_data.is_disabled);
    mutable_chromeos_data->set_oem_installed(chromeos_data.oem_installed);
    mutable_chromeos_data->set_handles_file_open_intents(
        chromeos_data.handles_file_open_intents);
  }

  if (web_app.client_data().system_web_app_data.has_value()) {
    auto& swa_data = web_app.client_data().system_web_app_data.value();

    auto* mutable_swa_data =
        local_data->mutable_client_data()->mutable_system_web_app_data();
    mutable_swa_data->set_system_app_type(
        static_cast<SystemWebAppDataProto_SystemAppType>(
            swa_data.system_app_type));
  }

  local_data->set_user_run_on_os_login_mode(
      ToWebAppProtoRunOnOsLoginMode(web_app.run_on_os_login_mode()));
  if (web_app.run_on_os_login_os_integration_state()) {
    local_data->set_run_on_os_login_os_integration_state(
        ToWebAppProtoRunOnOsLoginMode(
            *web_app.run_on_os_login_os_integration_state()));
  }
  local_data->set_is_from_sync_and_pending_installation(
      web_app.is_from_sync_and_pending_installation());
  local_data->set_is_uninstalling(web_app.is_uninstalling());

  for (const apps::IconInfo& icon_info : web_app.manifest_icons())
    *(local_data->add_manifest_icons()) = AppIconInfoToSyncProto(icon_info);

  for (SquareSizePx size : web_app.downloaded_icon_sizes(IconPurpose::ANY)) {
    local_data->add_downloaded_icon_sizes_purpose_any(size);
  }
  for (SquareSizePx size :
       web_app.downloaded_icon_sizes(IconPurpose::MASKABLE)) {
    local_data->add_downloaded_icon_sizes_purpose_maskable(size);
  }
  for (SquareSizePx size :
       web_app.downloaded_icon_sizes(IconPurpose::MONOCHROME)) {
    local_data->add_downloaded_icon_sizes_purpose_monochrome(size);
  }

  local_data->set_is_generated_icon(web_app.is_generated_icon());

  for (const auto& file_handler : web_app.file_handlers()) {
    WebAppFileHandlerProto* file_handler_proto =
        local_data->add_file_handlers();
    DCHECK(file_handler.action.is_valid());
    file_handler_proto->set_action(file_handler.action.spec());
    file_handler_proto->set_display_name(
        base::UTF16ToUTF8(file_handler.display_name));

    for (const auto& accept_entry : file_handler.accept) {
      WebAppFileHandlerAcceptProto* accept_entry_proto =
          file_handler_proto->add_accept();
      accept_entry_proto->set_mimetype(accept_entry.mime_type);

      for (const auto& file_extension : accept_entry.file_extensions)
        accept_entry_proto->add_file_extensions(file_extension);
    }

    for (const apps::IconInfo& icon_info : file_handler.downloaded_icons) {
      *(file_handler_proto->add_downloaded_icons()) =
          AppIconInfoToSyncProto(icon_info);
    }
  }

  if (web_app.share_target()) {
    const apps::ShareTarget& share_target = *web_app.share_target();
    auto* const mutable_share_target = local_data->mutable_share_target();
    mutable_share_target->set_action(share_target.action.spec());
    mutable_share_target->set_method(MethodToProto(share_target.method));
    mutable_share_target->set_enctype(EnctypeToProto(share_target.enctype));

    const apps::ShareTarget::Params& params = share_target.params;
    auto* const mutable_share_target_params =
        mutable_share_target->mutable_params();
    if (!params.title.empty())
      mutable_share_target_params->set_title(params.title);
    if (!params.text.empty())
      mutable_share_target_params->set_text(params.text);
    if (!params.url.empty())
      mutable_share_target_params->set_url(params.url);

    for (const auto& files_entry : params.files) {
      ShareTargetParamsFile* mutable_share_target_files =
          mutable_share_target_params->add_files();
      mutable_share_target_files->set_name(files_entry.name);

      for (const auto& file_type : files_entry.accept)
        mutable_share_target_files->add_accept(file_type);
    }
  }

  for (const WebAppShortcutsMenuItemInfo& shortcut_info :
       web_app.shortcuts_menu_item_infos()) {
    WebAppShortcutsMenuItemInfoProto* shortcut_info_proto =
        local_data->add_shortcuts_menu_item_infos();
    shortcut_info_proto->set_name(base::UTF16ToUTF8(shortcut_info.name));
    shortcut_info_proto->set_url(shortcut_info.url.spec());
    for (IconPurpose purpose : kIconPurposes) {
      for (const WebAppShortcutsMenuItemInfo::Icon& icon_info :
           shortcut_info.GetShortcutIconInfosForPurpose(purpose)) {
        sync_pb::WebAppIconInfo* shortcut_icon_info_proto;
        switch (purpose) {
          case IconPurpose::ANY:
            shortcut_icon_info_proto =
                shortcut_info_proto->add_shortcut_manifest_icons();
            break;
          case IconPurpose::MASKABLE:
            shortcut_icon_info_proto =
                shortcut_info_proto->add_shortcut_manifest_icons_maskable();
            break;
          case IconPurpose::MONOCHROME:
            shortcut_icon_info_proto =
                shortcut_info_proto->add_shortcut_manifest_icons_monochrome();
            break;
        }

        DCHECK(!icon_info.url.is_empty());
        shortcut_icon_info_proto->set_url(icon_info.url.spec());
        shortcut_icon_info_proto->set_size_in_px(icon_info.square_size_px);
      }
    }
  }

  for (const IconSizes& icon_sizes :
       web_app.downloaded_shortcuts_menu_icons_sizes()) {
    DownloadedShortcutsMenuIconSizesProto* icon_sizes_proto =
        local_data->add_downloaded_shortcuts_menu_icons_sizes();
    for (const SquareSizePx& icon_size :
         icon_sizes.GetSizesForPurpose(IconPurpose::ANY)) {
      icon_sizes_proto->add_icon_sizes(icon_size);
    }
    for (const SquareSizePx& icon_size :
         icon_sizes.GetSizesForPurpose(IconPurpose::MASKABLE)) {
      icon_sizes_proto->add_icon_sizes_maskable(icon_size);
    }
    for (const SquareSizePx& icon_size :
         icon_sizes.GetSizesForPurpose(IconPurpose::MONOCHROME)) {
      icon_sizes_proto->add_icon_sizes_monochrome(icon_size);
    }
  }

  for (const auto& additional_search_term : web_app.additional_search_terms()) {
    // Additional search terms should be sanitized before being added here.
    DCHECK(!additional_search_term.empty());
    local_data->add_additional_search_terms(additional_search_term);
  }

  for (const auto& protocol_handler : web_app.protocol_handlers()) {
    WebAppProtocolHandler* protocol_handler_proto =
        local_data->add_protocol_handlers();
    protocol_handler_proto->set_protocol(protocol_handler.protocol);
    protocol_handler_proto->set_url(protocol_handler.url.spec());
  }

  for (const auto& allowed_launch_protocols :
       web_app.allowed_launch_protocols()) {
    DCHECK(!allowed_launch_protocols.empty());
    local_data->add_allowed_launch_protocols(allowed_launch_protocols);
  }

  for (const auto& disallowed_launch_protocols :
       web_app.disallowed_launch_protocols()) {
    DCHECK(!disallowed_launch_protocols.empty());
    local_data->add_disallowed_launch_protocols(disallowed_launch_protocols);
  }

  for (const auto& url_handler : web_app.url_handlers()) {
    WebAppUrlHandlerProto* url_handler_proto = local_data->add_url_handlers();
    url_handler_proto->set_origin(url_handler.origin.Serialize());
    url_handler_proto->set_has_origin_wildcard(url_handler.has_origin_wildcard);
  }

  if (web_app.note_taking_new_note_url().is_valid()) {
    local_data->set_note_taking_new_note_url(
        web_app.note_taking_new_note_url().spec());
  }

  if (web_app.capture_links() != blink::mojom::CaptureLinks::kUndefined)
    local_data->set_capture_links(CaptureLinksToProto(web_app.capture_links()));
  else
    local_data->clear_capture_links();

  if (web_app.handle_links() != blink::mojom::HandleLinks::kUndefined)
    local_data->set_handle_links(HandleLinksToProto(web_app.handle_links()));
  else
    local_data->clear_handle_links();

  if (!web_app.manifest_url().is_empty())
    local_data->set_manifest_url(web_app.manifest_url().spec());

  local_data->set_file_handler_approval_state(
      ApiApprovalStateToProto(web_app.file_handler_approval_state()));

  local_data->set_file_handler_os_integration_state(
      OsIntegrationStateToProto(web_app.file_handler_os_integration_state()));

  local_data->set_window_controls_overlay_enabled(
      web_app.window_controls_overlay_enabled());

  local_data->set_is_storage_isolated(web_app.IsStorageIsolated());

  if (web_app.launch_handler()) {
    LaunchHandlerProto& launch_handler_proto =
        *local_data->mutable_launch_handler();
    launch_handler_proto.set_route_to(
        LaunchHandlerRouteToToProto(web_app.launch_handler()->route_to));
    launch_handler_proto.set_navigate_existing_client(
        LaunchHandlerNavigateExistingClientToProto(
            web_app.launch_handler()->navigate_existing_client));
  }

  if (web_app.parent_app_id_) {
    local_data->set_parent_app_id(*web_app.parent_app_id_);
  }

  if (!web_app.permissions_policy().empty()) {
    auto& policy = *local_data->mutable_permissions_policy();
    for (const auto& decl : web_app.permissions_policy()) {
      WebAppPermissionsPolicy proto_policy;
      proto_policy.set_feature(decl.feature);
      for (const auto& origin : decl.allowlist) {
        proto_policy.add_allowlist(origin);
      }
      policy.Add(std::move(proto_policy));
    }
  }

  return local_data;
}

// static
std::unique_ptr<WebApp> WebAppDatabase::CreateWebApp(
    const WebAppProto& local_data) {
  if (!local_data.has_sync_data()) {
    DLOG(ERROR) << "WebApp proto parse error: no sync_data field";
    return nullptr;
  }

  const sync_pb::WebAppSpecifics& sync_data = local_data.sync_data();

  // AppId is a hash of start_url. Read start_url first:
  GURL start_url(sync_data.start_url());
  if (start_url.is_empty() || !start_url.is_valid()) {
    DLOG(ERROR) << "WebApp proto start_url parse error: "
                << start_url.possibly_invalid_spec();
    return nullptr;
  }

  absl::optional<std::string> manifest_id = absl::nullopt;
  if (sync_data.has_manifest_id())
    manifest_id = absl::optional<std::string>(sync_data.manifest_id());

  const AppId app_id = GenerateAppId(manifest_id, start_url);

  auto web_app = std::make_unique<WebApp>(app_id);
  web_app->SetStartUrl(start_url);

  web_app->SetManifestId(manifest_id);

  // Required fields:
  if (!local_data.has_sources()) {
    DLOG(ERROR) << "WebApp proto parse error: no sources field";
    return nullptr;
  }

  WebAppSources sources;
  sources[Source::kSystem] = local_data.sources().system();
  sources[Source::kPolicy] = local_data.sources().policy();
  sources[Source::kWebAppStore] = local_data.sources().web_app_store();
  sources[Source::kSync] = local_data.sources().sync();
  sources[Source::kDefault] = local_data.sources().default_();
  if (local_data.sources().has_sub_app()) {
    sources[Source::kSubApp] = local_data.sources().sub_app();
  }
  if (!sources.any()) {
    DLOG(ERROR) << "WebApp proto parse error: no any source in sources field";
    return nullptr;
  }
  web_app->sources_ = sources;

  if (!local_data.has_name()) {
    DLOG(ERROR) << "WebApp proto parse error: no name field";
    return nullptr;
  }
  web_app->SetName(local_data.name());

  if (!sync_data.has_user_display_mode()) {
    DLOG(ERROR) << "WebApp proto parse error: no user_display_mode field";
    return nullptr;
  }
  web_app->SetUserDisplayMode(
      ToMojomDisplayMode(sync_data.user_display_mode()));

  // Ordinals used for chrome://apps page.
  syncer::StringOrdinal page_ordinal =
      syncer::StringOrdinal(sync_data.user_page_ordinal());
  if (!page_ordinal.IsValid())
    page_ordinal = syncer::StringOrdinal();
  syncer::StringOrdinal launch_ordinal =
      syncer::StringOrdinal(sync_data.user_launch_ordinal());
  if (!launch_ordinal.IsValid())
    launch_ordinal = syncer::StringOrdinal();
  web_app->SetUserPageOrdinal(page_ordinal);
  web_app->SetUserLaunchOrdinal(launch_ordinal);

  if (!local_data.has_is_locally_installed()) {
    DLOG(ERROR) << "WebApp proto parse error: no is_locally_installed field";
    return nullptr;
  }
  web_app->SetIsLocallyInstalled(local_data.is_locally_installed());

  auto& chromeos_data_proto = local_data.chromeos_data();

  if (IsChromeOsDataMandatory() && !local_data.has_chromeos_data()) {
    DLOG(ERROR) << "WebApp proto parse error: no chromeos_data field. The web "
                << "app might have been installed when running on an OS other "
                << "than Chrome OS.";
    return nullptr;
  }

  if (!IsChromeOsDataMandatory() && local_data.has_chromeos_data()) {
    DLOG(ERROR) << "WebApp proto parse error: has chromeos_data field. The web "
                << "app might have been installed when running on Chrome OS.";
    return nullptr;
  }

  if (local_data.has_chromeos_data()) {
    auto chromeos_data = absl::make_optional<WebAppChromeOsData>();
    chromeos_data->show_in_launcher = chromeos_data_proto.show_in_launcher();
    chromeos_data->show_in_search = chromeos_data_proto.show_in_search();
    chromeos_data->show_in_management =
        chromeos_data_proto.show_in_management();
    chromeos_data->is_disabled = chromeos_data_proto.is_disabled();
    chromeos_data->oem_installed = chromeos_data_proto.oem_installed();
    chromeos_data->handles_file_open_intents =
        chromeos_data_proto.handles_file_open_intents();
    web_app->SetWebAppChromeOsData(std::move(chromeos_data));
  }

  if (local_data.client_data().has_system_web_app_data()) {
    WebAppSystemWebAppData& swa_data =
        web_app->client_data()->system_web_app_data.emplace();

    swa_data.system_app_type = static_cast<SystemAppType>(
        local_data.client_data().system_web_app_data().system_app_type());
  }

  // Optional fields:
  if (local_data.has_launch_query_params())
    web_app->SetLaunchQueryParams(local_data.launch_query_params());

  if (local_data.has_display_mode())
    web_app->SetDisplayMode(ToMojomDisplayMode(local_data.display_mode()));

  std::vector<DisplayMode> display_mode_override;
  for (int i = 0; i < local_data.display_mode_override_size(); i++) {
    WebAppProto::DisplayMode display_mode = local_data.display_mode_override(i);
    display_mode_override.push_back(ToMojomDisplayMode(display_mode));
  }
  web_app->SetDisplayModeOverride(std::move(display_mode_override));

  if (local_data.has_description())
    web_app->SetDescription(local_data.description());

  if (local_data.has_scope()) {
    GURL scope(local_data.scope());
    if (scope.is_empty() || !scope.is_valid()) {
      DLOG(ERROR) << "WebApp proto scope parse error: "
                  << scope.possibly_invalid_spec();
      return nullptr;
    }
    web_app->SetScope(scope);
  }

  if (local_data.has_theme_color()) {
    web_app->SetThemeColor(local_data.theme_color());
  }

  if (local_data.has_dark_mode_theme_color()) {
    web_app->SetDarkModeThemeColor(local_data.dark_mode_theme_color());
  }

  if (local_data.has_background_color()) {
    web_app->SetBackgroundColor(local_data.background_color());
  }

  if (local_data.has_dark_mode_background_color()) {
    web_app->SetDarkModeBackgroundColor(
        local_data.dark_mode_background_color());
  }

  if (local_data.has_is_from_sync_and_pending_installation())
    web_app->SetIsFromSyncAndPendingInstallation(
        local_data.is_from_sync_and_pending_installation());

  if (local_data.has_is_uninstalling())
    web_app->SetIsUninstalling(local_data.is_uninstalling());

  if (local_data.has_last_badging_time()) {
    web_app->SetLastBadgingTime(
        syncer::ProtoTimeToTime(local_data.last_badging_time()));
  }
  if (local_data.has_last_launch_time()) {
    web_app->SetLastLaunchTime(
        syncer::ProtoTimeToTime(local_data.last_launch_time()));
  }
  if (local_data.has_install_source_for_metrics()) {
    int install_source = local_data.install_source_for_metrics();
    if (install_source >= 0 &&
        install_source <
            static_cast<int>(webapps::WebappInstallSource::COUNT)) {
      web_app->SetInstallSourceForMetrics(
          static_cast<webapps::WebappInstallSource>(install_source));
    }
  }
  if (local_data.has_manifest_update_time()) {
    web_app->SetManifestUpdateTime(
        syncer::ProtoTimeToTime(local_data.manifest_update_time()));
  }

  if (local_data.has_install_time()) {
    web_app->SetInstallTime(syncer::ProtoTimeToTime(local_data.install_time()));
  }

  absl::optional<WebApp::SyncFallbackData> parsed_sync_fallback_data =
      ParseSyncFallbackDataStruct(sync_data);
  if (!parsed_sync_fallback_data.has_value()) {
    // ParseSyncFallbackDataStruct() reports any errors.
    return nullptr;
  }
  web_app->SetSyncFallbackData(std::move(parsed_sync_fallback_data.value()));

  absl::optional<std::vector<apps::IconInfo>> parsed_manifest_icons =
      ParseAppIconInfos("WebApp", local_data.manifest_icons());
  if (!parsed_manifest_icons) {
    // ParseWebAppIconInfos() reports any errors.
    return nullptr;
  }
  web_app->SetManifestIcons(std::move(parsed_manifest_icons.value()));

  std::vector<SquareSizePx> icon_sizes_any;
  for (int32_t size : local_data.downloaded_icon_sizes_purpose_any())
    icon_sizes_any.push_back(size);
  web_app->SetDownloadedIconSizes(IconPurpose::ANY,
                                  SortedSizesPx(std::move(icon_sizes_any)));

  std::vector<SquareSizePx> icon_sizes_maskable;
  for (int32_t size : local_data.downloaded_icon_sizes_purpose_maskable())
    icon_sizes_maskable.push_back(size);
  web_app->SetDownloadedIconSizes(
      IconPurpose::MASKABLE, SortedSizesPx(std::move(icon_sizes_maskable)));

  std::vector<SquareSizePx> icon_sizes_monochrome;
  for (int32_t size : local_data.downloaded_icon_sizes_purpose_monochrome())
    icon_sizes_monochrome.push_back(size);
  web_app->SetDownloadedIconSizes(
      IconPurpose::MONOCHROME, SortedSizesPx(std::move(icon_sizes_monochrome)));

  web_app->SetIsGeneratedIcon(local_data.is_generated_icon());

  apps::FileHandlers file_handlers;
  for (const auto& file_handler_proto : local_data.file_handlers()) {
    apps::FileHandler file_handler;
    file_handler.action = GURL(file_handler_proto.action());

    if (file_handler.action.is_empty() || !file_handler.action.is_valid()) {
      DLOG(ERROR) << "WebApp FileHandler proto action parse error";
      return nullptr;
    }

    if (file_handler_proto.has_display_name()) {
      file_handler.display_name =
          base::UTF8ToUTF16(file_handler_proto.display_name());
    }

    for (const auto& accept_entry_proto : file_handler_proto.accept()) {
      apps::FileHandler::AcceptEntry accept_entry;
      accept_entry.mime_type = accept_entry_proto.mimetype();
      for (const auto& file_extension : accept_entry_proto.file_extensions()) {
        if (base::Contains(accept_entry.file_extensions, file_extension)) {
          // We intentionally don't return a nullptr here; instead, duplicate
          // entries are absorbed.
          DLOG(ERROR) << "apps::FileHandler::AcceptEntry parsing encountered "
                      << "duplicate file extension";
        }
        accept_entry.file_extensions.insert(file_extension);
      }
      file_handler.accept.push_back(std::move(accept_entry));
    }

    if (WebAppFileHandlerManager::IconsEnabled()) {
      absl::optional<std::vector<apps::IconInfo>> file_handler_icon_infos =
          ParseAppIconInfos("WebApp", file_handler_proto.downloaded_icons());
      if (!file_handler_icon_infos) {
        // ParseAppIconInfos() reports any errors.
        return nullptr;
      }
      file_handler.downloaded_icons =
          std::move(file_handler_icon_infos.value());
    }

    file_handlers.push_back(std::move(file_handler));
  }
  web_app->SetFileHandlers(std::move(file_handlers));

  if (local_data.has_share_target()) {
    apps::ShareTarget share_target;
    const ShareTarget& local_share_target = local_data.share_target();
    const ShareTargetParams& local_share_target_params =
        local_share_target.params();

    GURL action(local_share_target.action());
    if (action.is_empty() || !action.is_valid()) {
      DLOG(ERROR) << "WebApp proto action parse error: "
                  << action.possibly_invalid_spec();
      return nullptr;
    }

    share_target.action = action;
    share_target.method = ProtoToMethod(local_share_target.method());
    share_target.enctype = ProtoToEnctype(local_share_target.enctype());

    if (local_share_target_params.has_title())
      share_target.params.title = local_share_target_params.title();
    if (local_share_target_params.has_text())
      share_target.params.text = local_share_target_params.text();
    if (local_share_target_params.has_url())
      share_target.params.url = local_share_target_params.url();

    for (const auto& share_target_params_file :
         local_share_target_params.files()) {
      apps::ShareTarget::Files files_entry;
      files_entry.name = share_target_params_file.name();
      for (const auto& file_type : share_target_params_file.accept()) {
        if (base::Contains(files_entry.accept, file_type)) {
          // We intentionally don't return a nullptr here; instead, duplicate
          // entries are absorbed.
          DLOG(ERROR) << "apps::ShareTarget::Files parsing encountered "
                      << "duplicate file type";
        } else {
          files_entry.accept.push_back(file_type);
        }
      }
      share_target.params.files.push_back(std::move(files_entry));
    }

    web_app->SetShareTarget(std::move(share_target));
  }

  std::vector<WebAppShortcutsMenuItemInfo> shortcuts_menu_item_infos;
  for (const auto& shortcut_info_proto :
       local_data.shortcuts_menu_item_infos()) {
    WebAppShortcutsMenuItemInfo shortcut_info;
    shortcut_info.name = base::UTF8ToUTF16(shortcut_info_proto.name());
    shortcut_info.url = GURL(shortcut_info_proto.url());
    for (IconPurpose purpose : kIconPurposes) {
      // This default init needed to infer the sophisticated protobuf type.
      const auto* shortcut_manifest_icons =
          &shortcut_info_proto.shortcut_manifest_icons();

      switch (purpose) {
        case IconPurpose::ANY:
          shortcut_manifest_icons =
              &shortcut_info_proto.shortcut_manifest_icons();
          break;
        case IconPurpose::MASKABLE:
          shortcut_manifest_icons =
              &shortcut_info_proto.shortcut_manifest_icons_maskable();
          break;
        case IconPurpose::MONOCHROME:
          shortcut_manifest_icons =
              &shortcut_info_proto.shortcut_manifest_icons_monochrome();
          break;
      }

      std::vector<WebAppShortcutsMenuItemInfo::Icon> manifest_icons;
      for (const auto& icon_info_proto : *shortcut_manifest_icons) {
        WebAppShortcutsMenuItemInfo::Icon shortcut_icon_info;
        shortcut_icon_info.square_size_px = icon_info_proto.size_in_px();
        shortcut_icon_info.url = GURL(icon_info_proto.url());
        manifest_icons.emplace_back(std::move(shortcut_icon_info));
      }
      shortcut_info.SetShortcutIconInfosForPurpose(purpose,
                                                   std::move(manifest_icons));
    }
    shortcuts_menu_item_infos.emplace_back(std::move(shortcut_info));
  }
  web_app->SetShortcutsMenuItemInfos(std::move(shortcuts_menu_item_infos));

  std::vector<IconSizes> shortcuts_menu_icons_sizes;
  for (const auto& shortcuts_icon_sizes_proto :
       local_data.downloaded_shortcuts_menu_icons_sizes()) {
    IconSizes icon_sizes;
    icon_sizes.SetSizesForPurpose(
        IconPurpose::ANY, std::vector<SquareSizePx>(
                              shortcuts_icon_sizes_proto.icon_sizes().begin(),
                              shortcuts_icon_sizes_proto.icon_sizes().end()));
    icon_sizes.SetSizesForPurpose(
        IconPurpose::MASKABLE,
        std::vector<SquareSizePx>(
            shortcuts_icon_sizes_proto.icon_sizes_maskable().begin(),
            shortcuts_icon_sizes_proto.icon_sizes_maskable().end()));
    icon_sizes.SetSizesForPurpose(
        IconPurpose::MONOCHROME,
        std::vector<SquareSizePx>(
            shortcuts_icon_sizes_proto.icon_sizes_monochrome().begin(),
            shortcuts_icon_sizes_proto.icon_sizes_monochrome().end()));

    shortcuts_menu_icons_sizes.push_back(std::move(icon_sizes));
  }
  web_app->SetDownloadedShortcutsMenuIconsSizes(
      std::move(shortcuts_menu_icons_sizes));

  std::vector<std::string> additional_search_terms;
  for (const std::string& additional_search_term :
       local_data.additional_search_terms()) {
    if (additional_search_term.empty()) {
      DLOG(ERROR) << "WebApp AdditionalSearchTerms proto action parse error";
      return nullptr;
    }
    additional_search_terms.push_back(additional_search_term);
  }
  web_app->SetAdditionalSearchTerms(std::move(additional_search_terms));

  std::vector<apps::ProtocolHandlerInfo> protocol_handlers;
  for (const auto& protocol_handler_proto : local_data.protocol_handlers()) {
    apps::ProtocolHandlerInfo protocol_handler;
    protocol_handler.protocol = protocol_handler_proto.protocol();
    GURL protocol_handler_url(protocol_handler_proto.url());
    if (protocol_handler_url.is_empty() || !protocol_handler_url.is_valid()) {
      DLOG(ERROR) << "WebApp ProtocolHandler proto url parse error: "
                  << protocol_handler_url.possibly_invalid_spec();
      return nullptr;
    }
    protocol_handler.url = protocol_handler_url;

    protocol_handlers.push_back(std::move(protocol_handler));
  }
  web_app->SetProtocolHandlers(std::move(protocol_handlers));

  std::vector<std::string> allowed_launch_protocols;
  for (const std::string& allowed_launch_protocol :
       local_data.allowed_launch_protocols()) {
    if (allowed_launch_protocol.empty()) {
      DLOG(ERROR) << "WebApp AllowedLaunchProtocols proto action parse error";
      return nullptr;
    }
    allowed_launch_protocols.push_back(allowed_launch_protocol);
  }
  web_app->SetAllowedLaunchProtocols(std::move(allowed_launch_protocols));

  std::vector<std::string> disallowed_launch_protocols;
  for (const std::string& disallowed_launch_protocol :
       local_data.disallowed_launch_protocols()) {
    if (disallowed_launch_protocol.empty()) {
      DLOG(ERROR)
          << "WebApp DisallowedLaunchProtocols proto action parse error";
      return nullptr;
    }
    disallowed_launch_protocols.push_back(disallowed_launch_protocol);
  }
  web_app->SetDisallowedLaunchProtocols(std::move(disallowed_launch_protocols));

  std::vector<apps::UrlHandlerInfo> url_handlers;
  for (const auto& url_handler_proto : local_data.url_handlers()) {
    apps::UrlHandlerInfo url_handler;

    url::Origin origin = url::Origin::Create(GURL(url_handler_proto.origin()));
    if (origin.opaque()) {
      DLOG(ERROR) << "WebApp UrlHandler proto url parse error: "
                  << origin.GetDebugString();
      return nullptr;
    }
    url_handler.origin = std::move(origin);
    url_handler.has_origin_wildcard = url_handler_proto.has_origin_wildcard();
    url_handlers.push_back(std::move(url_handler));
  }
  web_app->SetUrlHandlers(std::move(url_handlers));

  if (local_data.has_note_taking_new_note_url()) {
    web_app->SetNoteTakingNewNoteUrl(
        GURL(local_data.note_taking_new_note_url()));
  }

  if (local_data.has_user_run_on_os_login_mode()) {
    web_app->SetRunOnOsLoginMode(
        ToRunOnOsLoginMode(local_data.user_run_on_os_login_mode()));
  }

  if (local_data.has_run_on_os_login_os_integration_state()) {
    web_app->SetRunOnOsLoginOsIntegrationState(
        ToRunOnOsLoginMode(local_data.run_on_os_login_os_integration_state()));
  }

  if (local_data.has_capture_links())
    web_app->SetCaptureLinks(ProtoToCaptureLinks(local_data.capture_links()));
  else
    web_app->SetCaptureLinks(blink::mojom::CaptureLinks::kUndefined);

  if (local_data.has_handle_links())
    web_app->SetHandleLinks(ProtoToHandleLinks(local_data.handle_links()));
  else
    web_app->SetHandleLinks(blink::mojom::HandleLinks::kUndefined);

  if (local_data.has_manifest_url()) {
    GURL manifest_url(local_data.manifest_url());
    if (manifest_url.is_empty() || !manifest_url.is_valid()) {
      DLOG(ERROR) << "WebApp proto manifest_url parse error: "
                  << manifest_url.possibly_invalid_spec();
      return nullptr;
    }
    web_app->SetManifestUrl(manifest_url);
  }

  if (local_data.has_file_handler_approval_state()) {
    web_app->SetFileHandlerApprovalState(
        ProtoToApiApprovalState(local_data.file_handler_approval_state()));
  }

  if (local_data.has_file_handler_os_integration_state()) {
    web_app->SetFileHandlerOsIntegrationState(ProtoToOsIntegrationState(
        local_data.file_handler_os_integration_state()));
  }

  if (local_data.has_window_controls_overlay_enabled()) {
    web_app->SetWindowControlsOverlayEnabled(
        local_data.window_controls_overlay_enabled());
  }

  web_app->SetStorageIsolated(local_data.is_storage_isolated());

  if (local_data.has_launch_handler()) {
    LaunchHandler launch_handler;
    const LaunchHandlerProto& launch_handler_proto =
        local_data.launch_handler();
    if (launch_handler_proto.has_route_to()) {
      launch_handler.route_to =
          ProtoToLaunchHandlerRouteTo(launch_handler_proto.route_to());
    }
    if (launch_handler_proto.has_navigate_existing_client()) {
      launch_handler.navigate_existing_client =
          ProtoToLaunchHandlerNavigateExistingClient(
              launch_handler_proto.navigate_existing_client());
    }
    web_app->SetLaunchHandler(std::move(launch_handler));
  }

  if (local_data.has_parent_app_id()) {
    web_app->parent_app_id_ = local_data.parent_app_id();
  }

  if (local_data.permissions_policy_size()) {
    std::vector<PermissionsPolicyDeclaration> policy;
    for (const auto& decl_proto : local_data.permissions_policy()) {
      PermissionsPolicyDeclaration decl;
      decl.feature = decl_proto.feature();
      for (const std::string& origin : decl_proto.allowlist()) {
        decl.allowlist.push_back(origin);
      }
      policy.push_back(decl);
    }
    web_app->SetPermissionsPolicy(policy);
  }

  return web_app;
}

void WebAppDatabase::OnDatabaseOpened(
    RegistryOpenedCallback callback,
    const absl::optional<syncer::ModelError>& error,
    std::unique_ptr<syncer::ModelTypeStore> store) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (error) {
    error_callback_.Run(*error);
    DLOG(ERROR) << "WebApps LevelDB opening error: " << error->ToString();
    return;
  }

  store_ = std::move(store);
  // TODO(loyso): Use ReadAllDataAndPreprocess to parse protos in the background
  // sequence.
  store_->ReadAllData(base::BindOnce(&WebAppDatabase::OnAllDataRead,
                                     weak_ptr_factory_.GetWeakPtr(),
                                     std::move(callback)));
}

void WebAppDatabase::OnAllDataRead(
    RegistryOpenedCallback callback,
    const absl::optional<syncer::ModelError>& error,
    std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (error) {
    error_callback_.Run(*error);
    DLOG(ERROR) << "WebApps LevelDB data read error: " << error->ToString();
    return;
  }

  store_->ReadAllMetadata(base::BindOnce(
      &WebAppDatabase::OnAllMetadataRead, weak_ptr_factory_.GetWeakPtr(),
      std::move(data_records), std::move(callback)));
}

void WebAppDatabase::OnAllMetadataRead(
    std::unique_ptr<syncer::ModelTypeStore::RecordList> data_records,
    RegistryOpenedCallback callback,
    const absl::optional<syncer::ModelError>& error,
    std::unique_ptr<syncer::MetadataBatch> metadata_batch) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (error) {
    error_callback_.Run(*error);
    DLOG(ERROR) << "WebApps LevelDB metadata read error: " << error->ToString();
    return;
  }

  Registry registry;
  for (const syncer::ModelTypeStore::Record& record : *data_records) {
    const AppId app_id = record.id;
    std::unique_ptr<WebApp> web_app = ParseWebApp(app_id, record.value);
    if (web_app)
      registry.emplace(app_id, std::move(web_app));
  }

  opened_ = true;
  // This should be a tail call: a callback code may indirectly call |this|
  // methods, like WebAppDatabase::Write()
  std::move(callback).Run(std::move(registry), std::move(metadata_batch));
}

void WebAppDatabase::OnDataWritten(
    CompletionCallback callback,
    const absl::optional<syncer::ModelError>& error) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (error) {
    error_callback_.Run(*error);
    DLOG(ERROR) << "WebApps LevelDB write error: " << error->ToString();
  }

  std::move(callback).Run(!error);
}

// static
std::unique_ptr<WebApp> WebAppDatabase::ParseWebApp(const AppId& app_id,
                                                    const std::string& value) {
  WebAppProto proto;
  const bool parsed = proto.ParseFromString(value);
  if (!parsed) {
    DLOG(ERROR) << "WebApps LevelDB parse error: can't parse proto.";
    return nullptr;
  }

  auto web_app = CreateWebApp(proto);
  if (!web_app) {
    // CreateWebApp() already logged what went wrong here.
    return nullptr;
  }

  if (web_app->app_id() != app_id) {
    DLOG(ERROR) << "WebApps LevelDB error: app_id doesn't match storage key";
    return nullptr;
  }

  return web_app;
}

DisplayMode ToMojomDisplayMode(WebAppProto::DisplayMode display_mode) {
  switch (display_mode) {
    case WebAppProto::BROWSER:
      return DisplayMode::kBrowser;
    case WebAppProto::MINIMAL_UI:
      return DisplayMode::kMinimalUi;
    case WebAppProto::STANDALONE:
      return DisplayMode::kStandalone;
    case WebAppProto::FULLSCREEN:
      return DisplayMode::kFullscreen;
    case WebAppProto::WINDOW_CONTROLS_OVERLAY:
      return DisplayMode::kWindowControlsOverlay;
    case WebAppProto::TABBED:
      return DisplayMode::kTabbed;
  }
}

DisplayMode ToMojomDisplayMode(
    ::sync_pb::WebAppSpecifics::UserDisplayMode user_display_mode) {
  switch (user_display_mode) {
    case ::sync_pb::WebAppSpecifics::BROWSER:
      return DisplayMode::kBrowser;
    case ::sync_pb::WebAppSpecifics::TABBED:
      return DisplayMode::kTabbed;
    // New display modes will most likely be of the window variety than the
    // browser tab variety so default to windowed if it's an enum value we don't
    // know about.
    case ::sync_pb::WebAppSpecifics::UNSPECIFIED:
    case ::sync_pb::WebAppSpecifics::STANDALONE:
      return DisplayMode::kStandalone;
  }
}

WebAppProto::DisplayMode ToWebAppProtoDisplayMode(DisplayMode display_mode) {
  switch (display_mode) {
    case DisplayMode::kBrowser:
      return WebAppProto::BROWSER;
    case DisplayMode::kMinimalUi:
      return WebAppProto::MINIMAL_UI;
    case DisplayMode::kUndefined:
      NOTREACHED();
      [[fallthrough]];
    case DisplayMode::kStandalone:
      return WebAppProto::STANDALONE;
    case DisplayMode::kFullscreen:
      return WebAppProto::FULLSCREEN;
    case DisplayMode::kWindowControlsOverlay:
      return WebAppProto::WINDOW_CONTROLS_OVERLAY;
    case DisplayMode::kTabbed:
      return WebAppProto::TABBED;
  }
}

}  // namespace web_app
