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

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

#include "base/check.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "chrome/browser/web_applications/proto/web_app.pb.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_database_factory.h"
#include "chrome/browser/web_applications/web_app_database_serialization.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 "chrome/common/chrome_features.h"
#include "components/sync/base/data_type.h"
#include "components/sync/model/data_type_store.h"
#include "components/sync/model/metadata_batch.h"
#include "components/sync/model/metadata_change_list.h"
#include "components/sync/model/model_error.h"
#include "components/sync/protocol/web_app_specifics.pb.h"
#include "components/webapps/browser/installable/installable_metrics.h"
#include "components/webapps/common/web_app_id.h"

namespace web_app {

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::OnceDataTypeStoreFactory 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::DataTypeStore::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 = WebAppToProto(*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 = WebAppToProto(*web_app);
    write_batch->WriteData(web_app->app_id(), proto->SerializeAsString());
  }

  for (const webapps::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
int WebAppDatabase::GetCurrentDatabaseVersion() {
  return 2;
}

WebAppDatabase::ProtobufState::ProtobufState() = default;
WebAppDatabase::ProtobufState::~ProtobufState() = default;
WebAppDatabase::ProtobufState::ProtobufState(ProtobufState&&) = default;
WebAppDatabase::ProtobufState& WebAppDatabase::ProtobufState::operator=(
    ProtobufState&&) = default;

WebAppDatabase::ProtobufState WebAppDatabase::ParseProtobufs(
    const syncer::DataTypeStore::RecordList& data_records) const {
  ProtobufState state;
  for (const syncer::DataTypeStore::Record& record : data_records) {
    if (record.id == kDatabaseMetadataKey) {
      bool success = state.metadata.ParseFromString(record.value);
      if (!success) {
        DLOG(ERROR)
            << "WebApps LevelDB parse error: can't parse metadata proto.";
        // TODO: Consider logging a histogram
      }
      continue;
    }

    proto::WebApp app_proto;
    bool success = app_proto.ParseFromString(record.value);
    if (!success) {
      DLOG(ERROR) << "WebApps LevelDB parse error: can't parse app proto.";
      // TODO: Consider logging a histogram
    }
    state.apps.emplace(record.id, std::move(app_proto));
  }
  return state;
}

void WebAppDatabase::MigrateDatabase(ProtobufState& state) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // Migration should happen when we have gotten a `store_`, but haven't
  // finished opening the database yet.
  CHECK(store_);
  CHECK(!opened_);

  bool did_change_metadata = false;
  std::set<webapps::AppId> changed_apps;

  // Upgrade from version 0 to version 1. This migrates the kSync source to
  // a combination of kSync and kUserInstalled.
  if (state.metadata.version() < 1 && GetCurrentDatabaseVersion() >= 1) {
    MigrateInstallSourceAddUserInstalled(state, changed_apps);
    base::UmaHistogramSparse("WebApp.Database.VersionUpgradedTo", 1);
    state.metadata.set_version(1);
    did_change_metadata = true;
  }

  // Upgrade from version 1 to version 2.
  if (state.metadata.version() < 2 && GetCurrentDatabaseVersion() >= 2) {
    MigrateShortcutAppsToDiyApps(state, changed_apps);
    MigrateDefaultDisplayModeToPlatformDisplayMode(state, changed_apps);
    MigratePartiallyInstalledAppsToCorrectState(state, changed_apps);
    base::UmaHistogramSparse("WebApp.Database.VersionUpgradedTo", 2);
    state.metadata.set_version(2);
    did_change_metadata = true;
  }

  CHECK_EQ(state.metadata.version(), GetCurrentDatabaseVersion());

  if (did_change_metadata || !changed_apps.empty()) {
    std::unique_ptr<syncer::DataTypeStore::WriteBatch> write_batch =
        store_->CreateWriteBatch();
    if (did_change_metadata) {
      write_batch->WriteData(std::string(kDatabaseMetadataKey),
                             state.metadata.SerializeAsString());
    }
    for (const auto& app_id : changed_apps) {
      CHECK(state.apps.contains(app_id));
      write_batch->WriteData(app_id, state.apps[app_id].SerializeAsString());
    }
    store_->CommitWriteBatch(
        std::move(write_batch),
        base::BindOnce(&WebAppDatabase::OnDataWritten,
                       weak_ptr_factory_.GetWeakPtr(), base::DoNothing()));
  }
}

void WebAppDatabase::MigrateInstallSourceAddUserInstalled(
    ProtobufState& state,
    std::set<webapps::AppId>& changed_apps) {
  // Migrating from version 0 to version 1.
  CHECK_LT(state.metadata.version(), 1);
  const bool is_syncing_apps = database_factory_->IsSyncingApps();
  int apps_migrated_count = 0;
  for (auto& [app_id, app_proto] : state.apps) {
    if (!app_proto.sources().sync()) {
      continue;
    }
    bool changed = false;
    if (!app_proto.sources().user_installed()) {
      app_proto.mutable_sources()->set_user_installed(true);
      changed = true;
    }
    if (!is_syncing_apps) {
      app_proto.mutable_sources()->set_sync(false);
      changed = true;
    }
    if (changed) {
      changed_apps.insert(app_id);
      apps_migrated_count++;
    }
  }
  base::UmaHistogramCounts1000(
      "WebApp.Migrations.InstallSourceAddUserInstalled", apps_migrated_count);
}

void WebAppDatabase::MigrateShortcutAppsToDiyApps(
    WebAppDatabase::ProtobufState& state,
    std::set<webapps::AppId>& changed_apps) {
  // Migrating from version 1 to version 2.
  CHECK_LT(state.metadata.version(), 2);
  int shortcut_to_diy_apps = 0;
  for (auto& [app_id, app_proto] : state.apps) {
    bool is_shortcut =
        !app_proto.has_scope() || app_proto.scope().empty() ||
        (app_proto.has_latest_install_source() &&
         app_proto.latest_install_source() ==
             static_cast<uint32_t>(
                 webapps::WebappInstallSource::MENU_CREATE_SHORTCUT));
    if (!is_shortcut) {
      continue;
    }
    changed_apps.insert(app_id);
    app_proto.set_is_diy_app(true);
    app_proto.set_was_shortcut_app(true);
    shortcut_to_diy_apps++;
    if (app_proto.has_scope() && !app_proto.scope().empty() &&
        GURL(app_proto.scope()).is_valid()) {
      continue;
    }
    // Populate the scope if it was empty or invalid.
    if (!app_proto.has_sync_data() || !app_proto.sync_data().has_start_url()) {
      DLOG(ERROR) << "Missing sync data or start_url for shortcut app "
                  << app_id;
      continue;
    }
    GURL start_url(app_proto.sync_data().start_url());
    if (!start_url.is_valid()) {
      // Cannot recover scope, mark for potential cleanup later if needed.
      DLOG(ERROR) << "Invalid start_url for shortcut app " << app_id << ":"
                  << start_url.possibly_invalid_spec();
      continue;
    }
    app_proto.set_scope(start_url.GetWithoutFilename().spec());
  }
  base::UmaHistogramCounts1000("WebApp.Migrations.ShortcutAppsToDiy2",
                               shortcut_to_diy_apps);
}

void WebAppDatabase::MigrateDefaultDisplayModeToPlatformDisplayMode(
    WebAppDatabase::ProtobufState& state,
    std::set<webapps::AppId>& changed_apps) {
  // Migrating from version 1 to version 2.
  CHECK_LT(state.metadata.version(), 2);
  int apps_migrated_count = 0;
  for (auto& [app_id, app_proto] : state.apps) {
    if (!app_proto.has_sync_data()) {
      // Cannot migrate without sync data.
      continue;
    }
    sync_pb::WebAppSpecifics* sync_data = app_proto.mutable_sync_data();
    if (!HasCurrentPlatformUserDisplayMode(*sync_data)) {
      sync_pb::WebAppSpecifics_UserDisplayMode udm =
          ResolvePlatformSpecificUserDisplayMode(*sync_data);
      SetPlatformSpecificUserDisplayMode(udm, sync_data);
      changed_apps.insert(app_id);
      apps_migrated_count++;
    }
  }
  base::UmaHistogramCounts1000("WebApp.Migrations.DefaultDisplayModeToPlatform",
                               apps_migrated_count);
}

// Corrects the install_state for apps that claim OS integration but lack the
// necessary OS integration state data.
void WebAppDatabase::MigratePartiallyInstalledAppsToCorrectState(
    WebAppDatabase::ProtobufState& state,
    std::set<webapps::AppId>& changed_apps) {
  // Migrating from version 1 to version 2.
  CHECK_LT(state.metadata.version(), 2);
  int install_state_fixed_count = 0;
  for (auto& [app_id, app_proto] : state.apps) {
    if (app_proto.install_state() !=
        proto::InstallState::INSTALLED_WITH_OS_INTEGRATION) {
      continue;
    }
    // Check if any OS integration state exists. A simple check for shortcut
    // presence is sufficient as a proxy for any OS integration.
    if (app_proto.has_current_os_integration_states() &&
        app_proto.current_os_integration_states().has_shortcut()) {
      continue;
    }
    app_proto.set_install_state(
        proto::InstallState::INSTALLED_WITHOUT_OS_INTEGRATION);
    changed_apps.insert(app_id);
    install_state_fixed_count++;
  }
  base::UmaHistogramCounts1000(
      "WebApp.Migrations.PartiallyInstalledAppsToCorrectState",
      install_state_fixed_count);
}

void WebAppDatabase::OnDatabaseOpened(
    RegistryOpenedCallback callback,
    const std::optional<syncer::ModelError>& error,
    std::unique_ptr<syncer::DataTypeStore> 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);
  store_->ReadAllDataAndMetadata(
      base::BindOnce(&WebAppDatabase::OnAllDataAndMetadataRead,
                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

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

  ProtobufState state = ParseProtobufs(*data_records);
  MigrateDatabase(state);

  Registry registry;
  for (const auto& [app_id, app_proto] : state.apps) {
    std::unique_ptr<WebApp> web_app = ParseWebAppProto(app_proto);
    if (!web_app) {
      continue;
    }

    if (web_app->app_id() != app_id) {
      DLOG(ERROR) << "WebApps LevelDB error: app_id doesn't match storage key "
                  << app_id << " vs " << web_app->app_id() << ", from "
                  << web_app->manifest_id();
      continue;
    }
    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 std::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);
}

}  // namespace web_app
