// Copyright (c) 2012 The Chromium OS 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 "update_engine/update_check_scheduler.h"

#include "update_engine/certificate_checker.h"
#include "update_engine/hardware_interface.h"
#include "update_engine/http_common.h"
#include "update_engine/system_state.h"
#include "update_engine/utils.h"

namespace chromeos_update_engine {

// Default update check timeout interval/fuzz values, in seconds. Note that
// actual fuzz is within +/- half of the indicated value.
const int UpdateCheckScheduler::kTimeoutInitialInterval    =  7 * 60;
const int UpdateCheckScheduler::kTimeoutPeriodicInterval   = 45 * 60;
const int UpdateCheckScheduler::kTimeoutMaxBackoffInterval =  4 * 60 * 60;
const int UpdateCheckScheduler::kTimeoutRegularFuzz        = 10 * 60;

UpdateCheckScheduler::UpdateCheckScheduler(UpdateAttempter* update_attempter,
                                           SystemState* system_state)
    : update_attempter_(update_attempter),
      enabled_(false),
      scheduled_(false),
      last_interval_(0),
      poll_interval_(0),
      system_state_(system_state) {}

UpdateCheckScheduler::~UpdateCheckScheduler() {}

void UpdateCheckScheduler::Run() {
  enabled_ = false;
  update_attempter_->set_update_check_scheduler(NULL);

  if (!system_state_->hardware()->IsOfficialBuild()) {
    LOG(WARNING) << "Non-official build: periodic update checks disabled.";
    return;
  }
  if (system_state_->hardware()->IsBootDeviceRemovable()) {
    LOG(WARNING) << "Removable device boot: periodic update checks disabled.";
    return;
  }
  enabled_ = true;

  // Registers this scheduler with the update attempter so that scheduler can be
  // notified of update status changes.
  update_attempter_->set_update_check_scheduler(this);

  // Kicks off periodic update checks. The first check is scheduled
  // |kTimeoutInitialInterval| seconds from now. Subsequent checks are scheduled
  // by ScheduleNextCheck, normally at |kTimeoutPeriodicInterval|-second
  // intervals.
  ScheduleCheck(kTimeoutInitialInterval, kTimeoutRegularFuzz);
}

guint UpdateCheckScheduler::GTimeoutAddSeconds(guint interval,
                                               GSourceFunc function) {
  return g_timeout_add_seconds(interval, function, this);
}

void UpdateCheckScheduler::ScheduleCheck(int interval, int fuzz) {
  if (!CanSchedule()) {
    return;
  }
  last_interval_ = interval;
  interval = utils::FuzzInt(interval, fuzz);
  if (interval < 0) {
    interval = 0;
  }
  GTimeoutAddSeconds(interval, StaticCheck);
  scheduled_ = true;
  LOG(INFO) << "Next update check in " << utils::FormatSecs(interval);
}

gboolean UpdateCheckScheduler::StaticCheck(void* scheduler) {
  UpdateCheckScheduler* me = reinterpret_cast<UpdateCheckScheduler*>(scheduler);
  CHECK(me->scheduled_);
  me->scheduled_ = false;

  if (me->system_state_->hardware()->IsOOBEComplete(nullptr)) {
    // Before updating, we flush any previously generated UMA reports.
    CertificateChecker::FlushReport();
    me->update_attempter_->Update("", "", false, false);
  } else {
    // Skips all automatic update checks if the OOBE process is not complete and
    // schedules a new check as if it is the first one.
    LOG(WARNING) << "Skipping update check because OOBE is not complete.";
    me->ScheduleCheck(kTimeoutInitialInterval, kTimeoutRegularFuzz);
  }
  // This check ensures that future update checks will be or are already
  // scheduled. The check should never fail. A check failure means that there's
  // a bug that will most likely prevent further automatic update checks. It
  // seems better to crash in such cases and restart the update_engine daemon
  // into, hopefully, a known good state.
  CHECK(me->update_attempter_->status() != UPDATE_STATUS_IDLE ||
        !me->CanSchedule());
  return FALSE;  // Don't run again.
}

void UpdateCheckScheduler::ComputeNextIntervalAndFuzz(int* next_interval,
                                                      int* next_fuzz) {
  CHECK(next_interval && next_fuzz);

  int interval = 0;
  int fuzz = 0;  // Use default fuzz value (see below)

  int http_response_code;
  if (poll_interval_ > 0) {
    // Server-dictated poll interval.
    interval = poll_interval_;
    LOG(WARNING) << "Using server-dictated poll interval: " << interval;
  } else if ((http_response_code = update_attempter_->http_response_code()) ==
             kHttpResponseInternalServerError ||
             http_response_code == kHttpResponseServiceUnavailable) {
    // Implements exponential backoff on 500 (Internal Server Error) and 503
    // (Service Unavailable) HTTP response codes.
    interval = 2 * last_interval_;
    LOG(WARNING) << "Exponential backoff due to HTTP response code ("
                 << http_response_code << ")";
  }

  // Backoff cannot exceed a predetermined maximum period.
  if (interval > kTimeoutMaxBackoffInterval)
    interval = kTimeoutMaxBackoffInterval;

  // Ensures that under normal conditions the regular update check interval
  // and fuzz are used. Also covers the case where backoff is required based
  // on the initial update check.
  if (interval < kTimeoutPeriodicInterval) {
    interval = kTimeoutPeriodicInterval;
    fuzz = kTimeoutRegularFuzz;
  }

  // Set default fuzz to +/- |interval|/2.
  if (fuzz == 0)
    fuzz = interval;

  *next_interval = interval;
  *next_fuzz = fuzz;
}

void UpdateCheckScheduler::ScheduleNextCheck() {
  int interval, fuzz;
  ComputeNextIntervalAndFuzz(&interval, &fuzz);
  ScheduleCheck(interval, fuzz);
}

void UpdateCheckScheduler::SetUpdateStatus(UpdateStatus status) {
  // We want to schedule the update checks for when we're idle as well as
  // after we've successfully applied an update and waiting for the user
  // to reboot to ensure our active count is accurate.
  if (status == UPDATE_STATUS_IDLE ||
      status == UPDATE_STATUS_UPDATED_NEED_REBOOT) {
    ScheduleNextCheck();
  }
}

}  // namespace chromeos_update_engine
