// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/updater/updater_module.h"

#include <map>
#include <utility>
#include <vector>

#include "base/bind_helpers.h"
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/optional.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/strcat.h"
#include "base/task/post_task.h"
#include "base/task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/version.h"
#include "cobalt/extension/installation_manager.h"
#include "cobalt/updater/crash_client.h"
#include "cobalt/updater/crash_reporter.h"
#include "cobalt/updater/util.h"
#include "components/crx_file/crx_verifier.h"
#include "components/update_client/utils.h"
#include "starboard/configuration_constants.h"
#include "starboard/loader_app/installation_manager.h"

namespace {

using update_client::ComponentState;

// The SHA256 hash of the "cobalt_evergreen_public" key.
constexpr uint8_t kCobaltPublicKeyHash[] = {
    0x51, 0xa8, 0xc0, 0x90, 0xf8, 0x1a, 0x14, 0xb0, 0xda, 0x7a, 0xfb,
    0x9e, 0x8b, 0x2d, 0x22, 0x65, 0x19, 0xb1, 0xfa, 0xba, 0x02, 0x04,
    0x3a, 0xb2, 0x7a, 0xf6, 0xfe, 0xd5, 0x35, 0xa1, 0x19, 0xd9};

// The map to translate updater status from enum to readable string.
const std::map<ComponentState, const char*> updater_status_map = {
    {ComponentState::kNew, "Will check for update soon"},
    {ComponentState::kChecking, "Checking for update"},
    {ComponentState::kCanUpdate, "Update is available"},
    {ComponentState::kDownloadingDiff, "Downloading delta update"},
    {ComponentState::kDownloading, "Downloading update"},
    {ComponentState::kDownloaded, "Update is downloaded"},
    {ComponentState::kUpdatingDiff, "Installing delta update"},
    {ComponentState::kUpdating, "Installing update"},
    {ComponentState::kUpdated, "Update installed, pending restart"},
    {ComponentState::kUpToDate, "App is up to date"},
    {ComponentState::kUpdateError, "Failed to update"},
    {ComponentState::kUninstalled, "Update uninstalled"},
    {ComponentState::kRun, "Transitioning..."},
    // ComponentState::kLastStatus is not meaningful to show to users.
};

void QuitLoop(base::OnceClosure quit_closure) { std::move(quit_closure).Run(); }

}  // namespace

namespace cobalt {
namespace updater {

void Observer::OnEvent(Events event, const std::string& id) {
  std::string status;
  if (update_client_->GetCrxUpdateState(id, &crx_update_item_)) {
    auto status_iterator = updater_status_map.find(crx_update_item_.state);
    if (status_iterator == updater_status_map.end()) {
      status = "Status is unknown.";
    } else {
      status = std::string(status_iterator->second);
    }
    if (crx_update_item_.state == ComponentState::kUpdateError) {
      status +=
          ", error code is " + std::to_string(crx_update_item_.error_code);
    }
  } else {
    status = "No status available";
  }
  updater_configurator_->SetUpdaterStatus(status);
  SB_LOG(INFO) << "Updater status is " << status;
}

UpdaterModule::UpdaterModule(network::NetworkModule* network_module)
    : updater_thread_("updater"), network_module_(network_module) {
  updater_thread_.StartWithOptions(
      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));

  DETACH_FROM_THREAD(thread_checker_);
  // Initialize the underlying update client.
  is_updater_running_ = true;
  updater_thread_.task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&UpdaterModule::Initialize, base::Unretained(this)));
}

UpdaterModule::~UpdaterModule() {
  if (is_updater_running_) {
    is_updater_running_ = false;
    updater_thread_.task_runner()->PostBlockingTask(
        FROM_HERE,
        base::Bind(&UpdaterModule::Finalize, base::Unretained(this)));
  }
}

void UpdaterModule::Suspend() {
  if (is_updater_running_) {
    is_updater_running_ = false;
    updater_thread_.task_runner()->PostBlockingTask(
        FROM_HERE,
        base::Bind(&UpdaterModule::Finalize, base::Unretained(this)));
  }
}

void UpdaterModule::Resume() {
  if (!is_updater_running_) {
    is_updater_running_ = true;
    updater_thread_.task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&UpdaterModule::Initialize, base::Unretained(this)));
  }
}

void UpdaterModule::Initialize() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // TODO: enable crash report with dependency on CrashPad
  // updater::crash_reporter::InitializeCrashKeys();

  // static crash_reporter::CrashKeyString<16> crash_key_process_type(
  //     "process_type");
  // crash_key_process_type.Set("updater");

  // if (CrashClient::GetInstance()->InitializeCrashReporting())
  //   VLOG(1) << "Crash reporting initialized.";
  // else
  //   VLOG(1) << "Crash reporting is not available.";

  // StartCrashReporter(UPDATER_VERSION_STRING);

  updater_configurator_ = base::MakeRefCounted<Configurator>(network_module_);
  update_client_ = update_client::UpdateClientFactory(updater_configurator_);

  updater_observer_.reset(new Observer(update_client_, updater_configurator_));
  update_client_->AddObserver(updater_observer_.get());

  // Schedule the first update check.
  updater_thread_.task_runner()->PostTask(
      FROM_HERE, base::Bind(&UpdaterModule::Update, base::Unretained(this)));
}

void UpdaterModule::Finalize() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  update_client_->RemoveObserver(updater_observer_.get());
  updater_observer_.reset();
  update_client_ = nullptr;

  updater_configurator_->GetPrefService()->CommitPendingWrite(
      base::BindOnce(&QuitLoop, base::Bind(base::DoNothing::Repeatedly())));

  updater_configurator_ = nullptr;
}

void UpdaterModule::MarkSuccessful() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  auto installation_manager =
      static_cast<const CobaltExtensionInstallationManagerApi*>(
          SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
  if (!installation_manager) {
    SB_LOG(ERROR) << "Updater failed to get installation manager extension.";
    return;
  }
  int index = installation_manager->GetCurrentInstallationIndex();
  if (index == IM_EXT_ERROR) {
    SB_LOG(ERROR) << "Updater failed to get current installation index.";
    return;
  }
  if (installation_manager->MarkInstallationSuccessful(index) !=
      IM_EXT_SUCCESS) {
    SB_LOG(ERROR)
        << "Updater failed to mark the current installation successful";
  }
}

void UpdaterModule::Update() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  // If updater_configurator_ is nullptr, the updater is suspended.
  if (updater_configurator_ == nullptr) {
    return;
  }
  const std::vector<std::string> app_ids = {
      updater_configurator_->GetAppGuid()};

  const base::Version manifest_version(GetEvergreenVersion());
  if (!manifest_version.IsValid()) {
    SB_LOG(ERROR) << "Updater failed to get the current update version.";
    return;
  }

  update_client_->Update(
      app_ids,
      base::BindOnce(
          [](base::Version manifest_version,
             const std::vector<std::string>& ids)
              -> std::vector<base::Optional<update_client::CrxComponent>> {
            update_client::CrxComponent component;
            component.name = "cobalt";
            component.app_id = ids[0];
            component.version = manifest_version;
            component.pk_hash.assign(std::begin(kCobaltPublicKeyHash),
                                     std::end(kCobaltPublicKeyHash));
            component.requires_network_encryption = true;
            component.crx_format_requirement = crx_file::VerifierFormat::CRX3;
            return {component};
          },
          manifest_version),
      false,
      base::BindOnce(
          [](base::OnceClosure closure, update_client::Error error) {
            base::ThreadTaskRunnerHandle::Get()->PostTask(
                FROM_HERE, base::BindOnce(&QuitLoop, std::move(closure)));
          },
          base::Bind(base::DoNothing::Repeatedly())));

  // Mark the current installation as successful.
  updater_thread_.task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&UpdaterModule::MarkSuccessful, base::Unretained(this)));

  IncrementUpdateCheckCount();

  int kNextUpdateCheckHours = 0;
  if (GetUpdateCheckCount() == 1) {
    // Update check ran once. The next check will be scheduled at a randomized
    // time between 1 and 24 hours.
    kNextUpdateCheckHours = base::RandInt(1, 24);
  } else {
    // Update check ran at least twice. The next check will be scheduled in 24
    // hours.
    kNextUpdateCheckHours = 24;
  }
  updater_thread_.task_runner()->PostDelayedTask(
      FROM_HERE, base::Bind(&UpdaterModule::Update, base::Unretained(this)),
      base::TimeDelta::FromHours(kNextUpdateCheckHours));
}

// The following three methods all called by the main web module thread.
std::string UpdaterModule::GetUpdaterChannel() const {
  return updater_configurator_->GetChannel();
}

void UpdaterModule::SetUpdaterChannel(const std::string& updater_channel) {
  updater_configurator_->SetChannel(updater_channel);
}

void UpdaterModule::RunUpdateCheck() {
  updater_thread_.task_runner()->PostTask(
      FROM_HERE, base::Bind(&UpdaterModule::Update, base::Unretained(this)));
}

}  // namespace updater
}  // namespace cobalt
