//
// Copyright (C) 2017 The Android Open Source Project
//
// 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 "update_engine/update_manager/android_things_policy.h"

#include <string>
#include <vector>

#include <base/logging.h>
#include <base/time/time.h>

#include "update_engine/update_manager/api_restricted_downloads_policy_impl.h"
#include "update_engine/update_manager/enough_slots_ab_updates_policy_impl.h"
#include "update_engine/update_manager/interactive_update_policy_impl.h"
#include "update_engine/update_manager/official_build_check_policy_impl.h"

using base::Time;
using chromeos_update_engine::ErrorCode;
using std::string;
using std::vector;

namespace chromeos_update_manager {

const NextUpdateCheckPolicyConstants
    AndroidThingsPolicy::kNextUpdateCheckPolicyConstants = {
        .timeout_initial_interval = 7 * 60,
        .timeout_periodic_interval = 5 * 60 * 60,
        .timeout_max_backoff_interval = 26 * 60 * 60,
        .timeout_regular_fuzz = 10 * 60,
        .attempt_backoff_max_interval_in_days = 16,
        .attempt_backoff_fuzz_in_hours = 12,
};

EvalStatus AndroidThingsPolicy::UpdateCheckAllowed(
    EvaluationContext* ec,
    State* state,
    string* error,
    UpdateCheckParams* result) const {
  // Set the default return values.
  result->updates_enabled = true;
  result->target_channel.clear();
  result->target_version_prefix.clear();
  result->is_interactive = false;

  // Build a list of policies to consult.  Note that each policy may modify the
  // result structure, even if it signals kContinue.
  EnoughSlotsAbUpdatesPolicyImpl enough_slots_ab_updates_policy;
  OnlyUpdateOfficialBuildsPolicyImpl only_update_official_builds_policy;
  InteractiveUpdatePolicyImpl interactive_update_policy;
  NextUpdateCheckTimePolicyImpl next_update_check_time_policy(
      kNextUpdateCheckPolicyConstants);

  vector<Policy const*> policies_to_consult = {
      // Do not perform any updates if there are not enough slots to do
      // A/B updates
      &enough_slots_ab_updates_policy,

      // Unofficial builds should not perform periodic update checks.
      &only_update_official_builds_policy,

      // Check to see if an interactive update was requested.
      &interactive_update_policy,

      // Ensure that periodic update checks are timed properly.
      &next_update_check_time_policy,
  };

  // Now that the list of policy implementations, and the order to consult them,
  // as been setup, do that.  If none of the policies make a definitive
  // decisions about whether or not to check for updates, then allow the update
  // check to happen.
  EvalStatus status = ConsultPolicies(policies_to_consult,
                                      &Policy::UpdateCheckAllowed,
                                      ec,
                                      state,
                                      error,
                                      result);
  if (status != EvalStatus::kContinue) {
    return status;
  } else {
    // It is time to check for an update.
    LOG(INFO) << "Allowing update check.";
    return EvalStatus::kSucceeded;
  }
}

// Uses the |UpdateRestrictions| to determine if the download and apply can
// occur at this time.
EvalStatus AndroidThingsPolicy::UpdateCanBeApplied(
    EvaluationContext* ec,
    State* state,
    string* error,
    ErrorCode* result,
    chromeos_update_engine::InstallPlan* install_plan) const {
  // Build a list of policies to consult.  Note that each policy may modify the
  // result structure, even if it signals kContinue.
  ApiRestrictedDownloadsPolicyImpl api_restricted_downloads_policy;

  vector<Policy const*> policies_to_consult = {
      // Do not apply the update if all updates are restricted by the API.
      &api_restricted_downloads_policy,
  };

  // Now that the list of policy implementations, and the order to consult them,
  // as been setup, do that.  If none of the policies make a definitive
  // decisions about whether or not to check for updates, then allow the update
  // check to happen.
  EvalStatus status = ConsultPolicies(policies_to_consult,
                                      &Policy::UpdateCanBeApplied,
                                      ec,
                                      state,
                                      error,
                                      result,
                                      install_plan);
  if (EvalStatus::kContinue != status) {
    return status;
  } else {
    // The update can proceed.
    LOG(INFO) << "Allowing update to be applied.";
    *result = ErrorCode::kSuccess;
    return EvalStatus::kSucceeded;
  }
}

// Always returns |EvalStatus::kSucceeded|
EvalStatus AndroidThingsPolicy::UpdateCanStart(EvaluationContext* ec,
                                               State* state,
                                               string* error,
                                               UpdateDownloadParams* result,
                                               UpdateState update_state) const {
  // Update is good to go.
  result->update_can_start = true;
  return EvalStatus::kSucceeded;
}

// Always returns |EvalStatus::kSucceeded|
EvalStatus AndroidThingsPolicy::UpdateDownloadAllowed(EvaluationContext* ec,
                                                      State* state,
                                                      string* error,
                                                      bool* result) const {
  // By default, we allow updates.
  *result = true;
  return EvalStatus::kSucceeded;
}

// P2P is always disabled.  Returns |result|==|false| and
// |EvalStatus::kSucceeded|
EvalStatus AndroidThingsPolicy::P2PEnabled(EvaluationContext* ec,
                                           State* state,
                                           string* error,
                                           bool* result) const {
  *result = false;
  return EvalStatus::kSucceeded;
}

// This will return immediately with |EvalStatus::kSucceeded| and set
// |result|==|false|
EvalStatus AndroidThingsPolicy::P2PEnabledChanged(EvaluationContext* ec,
                                                  State* state,
                                                  string* error,
                                                  bool* result,
                                                  bool prev_result) const {
  *result = false;
  return EvalStatus::kSucceeded;
}

}  // namespace chromeos_update_manager
