//
// 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_attempter_android.h"

#include <memory>
#include <string>

#include <android-base/properties.h>
#include <base/time/time.h>
#include <gtest/gtest.h>

#include "update_engine/common/fake_boot_control.h"
#include "update_engine/common/fake_clock.h"
#include "update_engine/common/fake_hardware.h"
#include "update_engine/common/fake_prefs.h"
#include "update_engine/common/mock_action_processor.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
#include "update_engine/daemon_state_android.h"
#include "update_engine/mock_metrics_reporter.h"

using base::Time;
using base::TimeDelta;
using testing::_;
using update_engine::UpdateStatus;

namespace chromeos_update_engine {

class UpdateAttempterAndroidTest : public ::testing::Test {
 protected:
  UpdateAttempterAndroidTest() = default;

  void SetUp() override {
    clock_ = new FakeClock();
    metrics_reporter_ = new testing::NiceMock<MockMetricsReporter>();
    update_attempter_android_.metrics_reporter_.reset(metrics_reporter_);
    update_attempter_android_.clock_.reset(clock_);
    update_attempter_android_.processor_.reset(
        new testing::NiceMock<MockActionProcessor>());
  }

  void SetUpdateStatus(update_engine::UpdateStatus status) {
    update_attempter_android_.status_ = status;
  }

  UpdateAttempterAndroid update_attempter_android_{
      &daemon_state_, &prefs_, &boot_control_, &hardware_};

  DaemonStateAndroid daemon_state_;
  FakePrefs prefs_;
  FakeBootControl boot_control_;
  FakeHardware hardware_;

  FakeClock* clock_;
  testing::NiceMock<MockMetricsReporter>* metrics_reporter_;
};

TEST_F(UpdateAttempterAndroidTest, UpdatePrefsSameBuildVersionOnInit) {
  std::string build_version =
      android::base::GetProperty("ro.build.version.incremental", "");
  prefs_.SetString(kPrefsPreviousVersion, build_version);
  prefs_.SetString(kPrefsBootId, "oldboot");
  prefs_.SetInt64(kPrefsNumReboots, 1);

  EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(_)).Times(0);
  update_attempter_android_.Init();

  // Check that the boot_id and reboot_count are updated.
  std::string boot_id;
  utils::GetBootId(&boot_id);
  EXPECT_TRUE(prefs_.Exists(kPrefsBootId));
  std::string prefs_boot_id;
  EXPECT_TRUE(prefs_.GetString(kPrefsBootId, &prefs_boot_id));
  EXPECT_EQ(boot_id, prefs_boot_id);

  EXPECT_TRUE(prefs_.Exists(kPrefsNumReboots));
  int64_t reboot_count;
  EXPECT_TRUE(prefs_.GetInt64(kPrefsNumReboots, &reboot_count));
  EXPECT_EQ(2, reboot_count);
}

TEST_F(UpdateAttempterAndroidTest, UpdatePrefsBuildVersionChangeOnInit) {
  prefs_.SetString(kPrefsPreviousVersion, "00001");  // Set the fake version
  prefs_.SetInt64(kPrefsPayloadAttemptNumber, 1);
  prefs_.SetInt64(kPrefsSystemUpdatedMarker, 23456);

  EXPECT_CALL(*metrics_reporter_,
              ReportAbnormallyTerminatedUpdateAttemptMetrics())
      .Times(1);

  Time now = Time::FromInternalValue(34456);
  clock_->SetMonotonicTime(now);
  TimeDelta duration = now - Time::FromInternalValue(23456);
  EXPECT_CALL(*metrics_reporter_, ReportTimeToReboot(duration.InMinutes()))
      .Times(1);

  update_attempter_android_.Init();
  // Check that we reset the metric prefs.
  EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots));
  EXPECT_FALSE(prefs_.Exists(kPrefsPayloadAttemptNumber));
  EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart));
  EXPECT_FALSE(prefs_.Exists(kPrefsSystemUpdatedMarker));
}

TEST_F(UpdateAttempterAndroidTest, ReportMetricsOnUpdateTerminated) {
  prefs_.SetInt64(kPrefsNumReboots, 3);
  prefs_.SetInt64(kPrefsPayloadAttemptNumber, 2);
  prefs_.SetString(kPrefsPreviousVersion, "56789");
  prefs_.SetInt64(kPrefsUpdateTimestampStart, 12345);

  Time boot_time = Time::FromInternalValue(22345);
  Time up_time = Time::FromInternalValue(21345);
  clock_->SetBootTime(boot_time);
  clock_->SetMonotonicTime(up_time);
  TimeDelta duration = boot_time - Time::FromInternalValue(12345);
  TimeDelta duration_uptime = up_time - Time::FromInternalValue(12345);
  EXPECT_CALL(
      *metrics_reporter_,
      ReportUpdateAttemptMetrics(_,
                                 2,
                                 _,
                                 duration,
                                 duration_uptime,
                                 _,
                                 metrics::AttemptResult::kUpdateSucceeded,
                                 ErrorCode::kSuccess))
      .Times(1);
  EXPECT_CALL(*metrics_reporter_,
              ReportSuccessfulUpdateMetrics(2, 0, _, _, _, _, duration, 3, _))
      .Times(1);

  SetUpdateStatus(UpdateStatus::UPDATE_AVAILABLE);
  update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kSuccess);

  EXPECT_FALSE(prefs_.Exists(kPrefsNumReboots));
  EXPECT_FALSE(prefs_.Exists(kPrefsPayloadAttemptNumber));
  EXPECT_FALSE(prefs_.Exists(kPrefsUpdateTimestampStart));
  EXPECT_TRUE(prefs_.Exists(kPrefsSystemUpdatedMarker));
}

TEST_F(UpdateAttempterAndroidTest, ReportMetricsForBytesDownloaded) {
  // Check both prefs are updated correctly.
  update_attempter_android_.BytesReceived(20, 50, 200);
  EXPECT_EQ(
      20,
      metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
  EXPECT_EQ(
      20,
      metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));

  EXPECT_CALL(*metrics_reporter_,
              ReportUpdateAttemptDownloadMetrics(50, _, _, _, _))
      .Times(1);
  EXPECT_CALL(*metrics_reporter_,
              ReportUpdateAttemptDownloadMetrics(40, _, _, _, _))
      .Times(1);

  int64_t total_bytes[kNumDownloadSources] = {};
  total_bytes[kDownloadSourceHttpsServer] = 90;
  EXPECT_CALL(*metrics_reporter_,
              ReportSuccessfulUpdateMetrics(
                  _,
                  _,
                  _,
                  _,
                  test_utils::DownloadSourceMatcher(total_bytes),
                  125,
                  _,
                  _,
                  _))
      .Times(1);

  // The first update fails after receiving 50 bytes in total.
  update_attempter_android_.BytesReceived(30, 50, 200);
  update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kError);
  EXPECT_EQ(
      0,
      metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
  EXPECT_EQ(
      50,
      metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));

  // The second update succeeds after receiving 40 bytes, which leads to a
  // overhead of 50 / 40 = 125%.
  update_attempter_android_.BytesReceived(40, 40, 50);
  update_attempter_android_.ProcessingDone(nullptr, ErrorCode::kSuccess);
  // Both prefs should be cleared.
  EXPECT_EQ(
      0,
      metrics_utils::GetPersistedValue(kPrefsCurrentBytesDownloaded, &prefs_));
  EXPECT_EQ(
      0, metrics_utils::GetPersistedValue(kPrefsTotalBytesDownloaded, &prefs_));
}

}  // namespace chromeos_update_engine
