// Copyright 2015 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 "components/arc/arc_session_runner.h"

#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "base/task_runner.h"
#include "components/arc/arc_util.h"

namespace arc {

namespace {

constexpr base::TimeDelta kDefaultRestartDelay =
    base::TimeDelta::FromSeconds(5);

void RecordInstanceCrashUma(ArcContainerLifetimeEvent sample) {
  UMA_HISTOGRAM_ENUMERATION("Arc.ContainerLifetimeEvent", sample,
                            ArcContainerLifetimeEvent::COUNT);
}

void RecordInstanceRestartAfterCrashUma(size_t restart_after_crash_count) {
  UMA_HISTOGRAM_COUNTS_100("Arc.ContainerRestartAfterCrashCount",
                           restart_after_crash_count);
}

// Gets an ArcContainerLifetimeEvent value to record. Returns nullopt when no
// UMA recording is needed.
base::Optional<ArcContainerLifetimeEvent> GetArcContainerLifetimeEvent(
    size_t restart_after_crash_count,
    ArcStopReason stop_reason,
    bool was_running) {
  // Record UMA only when this is the first non-early crash. This has to be
  // done before checking other conditions. Otherwise, an early crash after
  // container restart might be recorded. Each CONTAINER_STARTED event can
  // be paired up to one non-START event.
  if (restart_after_crash_count)
    return base::nullopt;

  switch (stop_reason) {
    case ArcStopReason::SHUTDOWN:
    case ArcStopReason::LOW_DISK_SPACE:
      // We don't record these events.
      return base::nullopt;
    case ArcStopReason::GENERIC_BOOT_FAILURE:
      return ArcContainerLifetimeEvent::CONTAINER_FAILED_TO_START;
    case ArcStopReason::CRASH:
      return was_running ? ArcContainerLifetimeEvent::CONTAINER_CRASHED
                         : ArcContainerLifetimeEvent::CONTAINER_CRASHED_EARLY;
  }

  NOTREACHED();
  return base::nullopt;
}

// Returns true if restart is needed for given conditions.
bool IsRestartNeeded(base::Optional<ArcInstanceMode> target_mode,
                     ArcStopReason stop_reason,
                     bool was_running) {
  if (!target_mode.has_value()) {
    // The request to run ARC is canceled by the caller. No need to restart.
    return false;
  }

  switch (stop_reason) {
    case ArcStopReason::SHUTDOWN:
      // This is a part of stop requested by ArcSessionRunner.
      // If ARC is re-requested to start, restart is necessary.
      // This case happens, e.g., RequestStart() -> RequestStop() ->
      // RequestStart(), case. If the second RequestStart() is called before
      // the instance previously running is stopped, then just |target_mode_|
      // is set. On completion, restart is needed.
      return true;
    case ArcStopReason::GENERIC_BOOT_FAILURE:
    case ArcStopReason::LOW_DISK_SPACE:
      // These two are errors on starting. To prevent failure loop, do not
      // restart.
      return false;
    case ArcStopReason::CRASH:
      // ARC instance is crashed unexpectedly, so automatically restart.
      // However, to avoid crash loop, do not restart if it is not successfully
      // started yet. So, check |was_running|.
      return was_running;
  }

  NOTREACHED();
  return false;
}

// Returns true if the request to start/upgrade ARC instance is allowed
// operation.
bool IsRequestAllowed(const base::Optional<ArcInstanceMode>& current_mode,
                      ArcInstanceMode request_mode) {
  if (!current_mode.has_value()) {
    // This is a request to start a new ARC instance (either mini instance
    // or full instance).
    return true;
  }

  if (current_mode == ArcInstanceMode::MINI_INSTANCE &&
      request_mode == ArcInstanceMode::FULL_INSTANCE) {
    // This is a request to upgrade the running mini instance to full instance.
    return true;
  }

  // Otherwise, not allowed.
  LOG(ERROR) << "Unexpected ARC instance mode transition request: "
             << current_mode << " -> " << request_mode;
  return false;
}

}  // namespace

ArcSessionRunner::ArcSessionRunner(const ArcSessionFactory& factory)
    : restart_delay_(kDefaultRestartDelay),
      restart_after_crash_count_(0),
      factory_(factory),
      weak_ptr_factory_(this) {
}

ArcSessionRunner::~ArcSessionRunner() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (arc_session_)
    arc_session_->RemoveObserver(this);
}

void ArcSessionRunner::AddObserver(Observer* observer) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  observer_list_.AddObserver(observer);
}

void ArcSessionRunner::RemoveObserver(Observer* observer) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  observer_list_.RemoveObserver(observer);
}

void ArcSessionRunner::RequestStartMiniInstance() {
  RequestStart(ArcInstanceMode::MINI_INSTANCE);
}

void ArcSessionRunner::RequestUpgrade(ArcSession::UpgradeParams params) {
  upgrade_params_ = std::move(params);
  RequestStart(ArcInstanceMode::FULL_INSTANCE);
}

void ArcSessionRunner::RequestStart(ArcInstanceMode request_mode) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  if (target_mode_ == request_mode) {
    // Consecutive RequestStart() call for the same mode. Do nothing.
    return;
  }

  if (!IsRequestAllowed(target_mode_, request_mode))
    return;

  VLOG(1) << "Session start requested: " << request_mode;
  target_mode_ = request_mode;
  if (arc_session_ && arc_session_->IsStopRequested()) {
    // This is the case where RequestStop() was called, but before
    // |arc_session_| had finshed stopping, RequestStart() is called.
    // Do nothing in the that case, since when |arc_session_| does actually
    // stop, OnSessionStopped() will be called, where it should automatically
    // restart.
    return;
  }

  if (restart_timer_.IsRunning()) {
    // |restart_timer_| may be running if this is upgrade request in a
    // following scenario.
    // - RequestStart(MINI_INSTANCE)
    // - RequestStop()
    // - RequestStart(MINI_INSTANCE)
    // - OnSessionStopped()
    // - RequestStart(FULL_INSTANCE) before RestartArcSession() is called.
    // In such a case, defer the operation to RestartArcSession() called later.
    return;
  }

  // No asynchronous event is expected later. Trigger the ArcSession now.
  StartArcSession();
}

void ArcSessionRunner::RequestStop() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  VLOG(1) << "Session stop requested";
  target_mode_ = base::nullopt;

  if (arc_session_) {
    // If |arc_session_| is running, stop it.
    // Note that |arc_session_| may be already in the process of stopping or
    // be stopped.
    // E.g. RequestStart() -> RequestStop() -> RequestStart() -> RequestStop()
    // case. If the second RequestStop() is called before the first
    // RequestStop() is not yet completed for the instance, Stop() of the
    // instance is called again, but it is no-op as expected.
    arc_session_->Stop();
  }

  // In case restarting is in progress, cancel it.
  restart_timer_.Stop();
}

void ArcSessionRunner::OnShutdown() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  VLOG(1) << "OnShutdown";
  target_mode_ = base::nullopt;
  restart_timer_.Stop();
  if (arc_session_)
    arc_session_->OnShutdown();
  // ArcSession::OnShutdown() invokes OnSessionStopped() synchronously.
  // In the observer method, |arc_session_| should be destroyed.
  DCHECK(!arc_session_);
}

void ArcSessionRunner::SetRestartDelayForTesting(
    const base::TimeDelta& restart_delay) {
  DCHECK(!arc_session_);
  DCHECK(!restart_timer_.IsRunning());
  restart_delay_ = restart_delay;
}

void ArcSessionRunner::StartArcSession() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(!restart_timer_.IsRunning());
  DCHECK(target_mode_.has_value());

  VLOG(1) << "Starting ARC instance";
  if (!arc_session_) {
    arc_session_ = factory_.Run();
    arc_session_->AddObserver(this);
    arc_session_->StartMiniInstance();
    // Record the UMA only when |restart_after_crash_count_| is zero to avoid
    // recording an auto-restart-then-crash loop. Such a crash loop is recorded
    // separately with RecordInstanceRestartAfterCrashUma().
    if (!restart_after_crash_count_)
      RecordInstanceCrashUma(ArcContainerLifetimeEvent::CONTAINER_STARTING);
  }
  if (target_mode_ == ArcInstanceMode::FULL_INSTANCE) {
    arc_session_->RequestUpgrade(std::move(upgrade_params_));
  }
}

void ArcSessionRunner::RestartArcSession() {
  VLOG(0) << "Restarting ARC instance";
  // The order is important here. Call StartArcSession(), then notify observers.
  StartArcSession();
  for (auto& observer : observer_list_)
    observer.OnSessionRestarting();
}

void ArcSessionRunner::OnSessionStopped(ArcStopReason stop_reason,
                                        bool was_running,
                                        bool full_requested) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(arc_session_);
  DCHECK(!restart_timer_.IsRunning());

  VLOG(0) << "ARC stopped: " << stop_reason;

  arc_session_->RemoveObserver(this);
  arc_session_.reset();

  const base::Optional<ArcContainerLifetimeEvent> uma_to_record =
      GetArcContainerLifetimeEvent(restart_after_crash_count_, stop_reason,
                                   was_running);
  if (uma_to_record.has_value())
    RecordInstanceCrashUma(uma_to_record.value());

  const bool restarting =
      IsRestartNeeded(target_mode_, stop_reason, was_running);

  if (restarting && stop_reason == ArcStopReason::CRASH) {
    ++restart_after_crash_count_;
  } else {
    // The session ended. Record the restart count.
    RecordInstanceRestartAfterCrashUma(restart_after_crash_count_);
    restart_after_crash_count_ = 0;
  }

  if (restarting) {
    // There was a previous invocation and it crashed for some reason. Try
    // starting ARC instance later again.
    // Note that even |restart_delay_| is 0 (for testing), it needs to
    // PostTask, because observer callback may call RequestStart()/Stop().
    VLOG(0) << "ARC restarting";
    restart_timer_.Start(FROM_HERE, restart_delay_,
                         base::BindOnce(&ArcSessionRunner::RestartArcSession,
                                        weak_ptr_factory_.GetWeakPtr()));
  }

  // The observers should be agnostic to the existence of the limited-purpose
  // instance.
  if (full_requested) {
    for (auto& observer : observer_list_)
      observer.OnSessionStopped(stop_reason, restarting);
  }
}

}  // namespace arc
