// Copyright 2018 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 "base/trace_event/cpufreq_monitor_android.h"

#include <list>

#include <fcntl.h>

#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace trace_event {

class TestTaskRunner : public SingleThreadTaskRunner {
 public:
  bool PostDelayedTask(const Location& from_here,
                       OnceClosure task,
                       base::TimeDelta delay) override {
    delayed_tasks_.push_back(std::make_pair(std::move(delay), std::move(task)));
    return true;
  }

  bool PostNonNestableDelayedTask(const Location& from_here,
                                  OnceClosure task,
                                  base::TimeDelta delay) override {
    NOTREACHED();
    return false;
  }

  bool RunsTasksInCurrentSequence() const override { return true; }

  // Returns the delay in ms for this task if there was a task to be run,
  // and -1 if there are no tasks in the queue.
  int64_t RunNextTask() {
    if (delayed_tasks_.size() == 0)
      return -1;
    auto time_delta = delayed_tasks_.front().first;
    std::move(delayed_tasks_.front().second).Run();
    delayed_tasks_.pop_front();
    return time_delta.InMilliseconds();
  }

 private:
  ~TestTaskRunner() final {}

  std::list<std::pair<base::TimeDelta, OnceClosure>> delayed_tasks_;
};

class TestDelegate : public CPUFreqMonitorDelegate {
 public:
  TestDelegate(const std::string& temp_dir_path)
      : temp_dir_path_(temp_dir_path) {}

  void set_trace_category_enabled(bool enabled) {
    trace_category_enabled_ = enabled;
  }

  void set_cpu_ids(const std::vector<unsigned int>& cpu_ids) {
    cpu_ids_ = cpu_ids;
  }

  void set_kernel_max_cpu(unsigned int kernel_max_cpu) {
    kernel_max_cpu_ = kernel_max_cpu;
  }

  const std::vector<std::pair<unsigned int, unsigned int>>& recorded_freqs() {
    return recorded_freqs_;
  }

  // CPUFreqMonitorDelegate implementation:
  void GetCPUIds(std::vector<unsigned int>* ids) const override {
    // Use the test values if available.
    if (cpu_ids_.size() > 0) {
      *ids = cpu_ids_;
      return;
    }
    // Otherwise fall back to the original function.
    CPUFreqMonitorDelegate::GetCPUIds(ids);
  }

  void RecordFrequency(unsigned int cpu_id, unsigned int freq) override {
    recorded_freqs_.emplace_back(
        std::pair<unsigned int, unsigned int>(cpu_id, freq));
  }

  bool IsTraceCategoryEnabled() const override {
    return trace_category_enabled_;
  }

  std::string GetScalingCurFreqPathString(unsigned int cpu_id) const override {
    return base::StringPrintf("%s/scaling_cur_freq%d", temp_dir_path_.c_str(),
                              cpu_id);
  }

  std::string GetRelatedCPUsPathString(unsigned int cpu_id) const override {
    return base::StringPrintf("%s/related_cpus%d", temp_dir_path_.c_str(),
                              cpu_id);
  }

  unsigned int GetKernelMaxCPUs() const override { return kernel_max_cpu_; }

 protected:
  scoped_refptr<SingleThreadTaskRunner> CreateTaskRunner() override {
    return base::WrapRefCounted(new TestTaskRunner());
  }

 private:
  // Maps CPU ID to frequency.
  std::vector<std::pair<unsigned int, unsigned int>> recorded_freqs_;

  std::vector<unsigned int> cpu_ids_;

  bool trace_category_enabled_ = true;
  std::string temp_dir_path_;
  unsigned int kernel_max_cpu_ = 0;
};

class CPUFreqMonitorTest : public testing::Test {
 public:
  CPUFreqMonitorTest() : testing::Test() {}

  void SetUp() override {
    temp_dir_ = std::make_unique<ScopedTempDir>();
    ASSERT_TRUE(temp_dir_->CreateUniqueTempDir());

    std::string base_path = temp_dir_->GetPath().value();
    auto delegate = std::make_unique<TestDelegate>(base_path);
    // Retain a pointer to the delegate since we're passing ownership to the
    // monitor but we need to be able to modify it.
    delegate_ = delegate.get();

    // Can't use make_unique because it's a private constructor.
    CPUFreqMonitor* monitor = new CPUFreqMonitor(std::move(delegate));
    monitor_.reset(monitor);
  }

  void TearDown() override {
    monitor_.reset();
    temp_dir_.reset();
  }

  void CreateDefaultScalingCurFreqFiles(
      const std::vector<std::pair<unsigned int, unsigned int>>& frequencies) {
    for (auto& pair : frequencies) {
      std::string file_path =
          delegate_->GetScalingCurFreqPathString(pair.first);
      std::string str_freq = base::StringPrintf("%d\n", pair.second);
      base::WriteFile(base::FilePath(file_path), str_freq.c_str(),
                      str_freq.length());
    }
  }

  void CreateRelatedCPUFiles(const std::vector<unsigned int>& clusters,
                             const std::vector<std::string>& related_cpus) {
    for (unsigned int i = 0; i < clusters.size(); i++) {
      base::WriteFile(base::FilePath(delegate_->GetRelatedCPUsPathString(i)),
                      related_cpus[clusters[i]].c_str(),
                      related_cpus[clusters[i]].length());
    }
  }

  void InitBasicCPUInfo() {
    std::vector<std::pair<unsigned int, unsigned int>> frequencies = {
        {0, 500}, {2, 1000}, {4, 800}, {6, 750},
    };
    std::vector<unsigned int> cpu_ids;
    for (auto& pair : frequencies) {
      cpu_ids.push_back(pair.first);
    }
    delegate()->set_cpu_ids(cpu_ids);

    CreateDefaultScalingCurFreqFiles(frequencies);
  }

  TestTaskRunner* GetOrCreateTaskRunner() {
    return static_cast<TestTaskRunner*>(
        monitor_->GetOrCreateTaskRunner().get());
  }

  CPUFreqMonitor* monitor() { return monitor_.get(); }
  ScopedTempDir* temp_dir() { return temp_dir_.get(); }
  TestDelegate* delegate() { return delegate_; }

 private:
  scoped_refptr<TestTaskRunner> task_runner_;
  std::unique_ptr<ScopedTempDir> temp_dir_;
  std::unique_ptr<CPUFreqMonitor> monitor_;
  TestDelegate* delegate_;
};

TEST_F(CPUFreqMonitorTest, TestStart) {
  InitBasicCPUInfo();
  monitor()->Start();
  ASSERT_TRUE(monitor()->IsEnabledForTesting());
}

TEST_F(CPUFreqMonitorTest, TestSample) {
  // Vector of CPU ID to frequency.
  std::vector<std::pair<unsigned int, unsigned int>> frequencies = {{0, 500},
                                                                    {4, 1000}};
  std::vector<unsigned int> cpu_ids;
  for (auto& pair : frequencies) {
    cpu_ids.push_back(pair.first);
  }
  delegate()->set_cpu_ids(cpu_ids);

  // Build some files with CPU frequency info in it to sample.
  std::vector<std::pair<unsigned int, base::ScopedFD>> fds;
  for (auto& pair : frequencies) {
    std::string file_path = base::StringPrintf(
        "%s/temp%d", temp_dir()->GetPath().value().c_str(), pair.first);

    // Uses raw file descriptors so we can build our ScopedFDs in the same loop.
    int fd = open(file_path.c_str(), O_RDWR | O_CREAT | O_SYNC,
                  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    ASSERT_FALSE(fd == -1);

    std::string str_freq = base::StringPrintf("%d\n", pair.second);
    write(fd, str_freq.c_str(), str_freq.length());
    fds.emplace_back(std::make_pair(pair.first, base::ScopedFD(fd)));
  }

  // This ensures we set it to enabled before sampling, otherwise the call to
  // Sample() will end early.
  CreateDefaultScalingCurFreqFiles(frequencies);
  monitor()->Start();
  ASSERT_TRUE(monitor()->IsEnabledForTesting());

  // Ensure that we run our undelayed posted task for Sample.
  ASSERT_EQ(GetOrCreateTaskRunner()->RunNextTask(), 0);
  // Run the new delayed task so we sample again.
  ASSERT_TRUE(GetOrCreateTaskRunner()->RunNextTask() ==
              CPUFreqMonitor::kDefaultCPUFreqSampleIntervalMs);

  // Ensure that the values that we recorded agree with the frequencies above.
  auto recorded_freqs = delegate()->recorded_freqs();
  ASSERT_EQ(recorded_freqs.size(), frequencies.size() * 2);
  for (unsigned int i = 0; i < frequencies.size(); i++) {
    auto freq_pair = frequencies[i];
    // We sampled twice, so the recording pairs should be equal.
    auto recorded_pair_1 = recorded_freqs[i];
    auto recorded_pair_2 = recorded_freqs[i + 2];
    ASSERT_EQ(freq_pair.first, recorded_pair_1.first);
    ASSERT_EQ(freq_pair.second, recorded_pair_1.second);
    ASSERT_EQ(freq_pair.first, recorded_pair_2.first);
    ASSERT_EQ(freq_pair.second, recorded_pair_2.second);
  }

  // Test that calling Stop works, we shouldn't post any more tasks if Sample
  // is called.
  monitor()->Stop();
  // Clear out the first Sample task that's on deck, then try again to make sure
  // no new task was posted.
  ASSERT_TRUE(GetOrCreateTaskRunner()->RunNextTask() ==
              CPUFreqMonitor::kDefaultCPUFreqSampleIntervalMs);
  ASSERT_EQ(GetOrCreateTaskRunner()->RunNextTask(), -1);
}

TEST_F(CPUFreqMonitorTest, TestStartFail_TraceCategoryDisabled) {
  delegate()->set_trace_category_enabled(false);
  CreateDefaultScalingCurFreqFiles({{0, 1000}});
  monitor()->Start();
  ASSERT_FALSE(monitor()->IsEnabledForTesting());
}

TEST_F(CPUFreqMonitorTest, TestStartFail_NoScalingCurFreqFiles) {
  monitor()->Start();
  ASSERT_FALSE(monitor()->IsEnabledForTesting());
}

TEST_F(CPUFreqMonitorTest, TestDelegate_GetCPUIds) {
  delegate()->set_kernel_max_cpu(8);
  std::vector<std::string> related_cpus = {"0 1 2 3\n", "4 5 6 7\n"};
  std::vector<unsigned int> clusters = {0, 0, 0, 0, 1, 1, 1, 1};

  CreateRelatedCPUFiles(clusters, related_cpus);

  std::vector<unsigned int> cpu_ids;
  delegate()->GetCPUIds(&cpu_ids);
  EXPECT_EQ(cpu_ids.size(), 2U);
  EXPECT_EQ(cpu_ids[0], 0U);
  EXPECT_EQ(cpu_ids[1], 4U);
}

TEST_F(CPUFreqMonitorTest, TestDelegate_GetCPUIds_FailReadingFallback) {
  delegate()->set_kernel_max_cpu(8);

  std::vector<unsigned int> cpu_ids;
  delegate()->GetCPUIds(&cpu_ids);
  EXPECT_EQ(cpu_ids.size(), 1U);
  EXPECT_EQ(cpu_ids[0], 0U);
}

TEST_F(CPUFreqMonitorTest, TestMultipleStartStop) {
  InitBasicCPUInfo();

  monitor()->Start();
  ASSERT_TRUE(monitor()->IsEnabledForTesting());
  monitor()->Stop();
  ASSERT_FALSE(monitor()->IsEnabledForTesting());

  monitor()->Start();
  ASSERT_TRUE(monitor()->IsEnabledForTesting());
  monitor()->Stop();
  ASSERT_FALSE(monitor()->IsEnabledForTesting());
}

TEST_F(CPUFreqMonitorTest, TestTraceLogEnableDisable) {
  InitBasicCPUInfo();

  monitor()->OnTraceLogEnabled();
  // OnTraceLogEnabled posts a task for Start.
  GetOrCreateTaskRunner()->RunNextTask();
  ASSERT_TRUE(monitor()->IsEnabledForTesting());
  monitor()->OnTraceLogDisabled();
  ASSERT_FALSE(monitor()->IsEnabledForTesting());
  // We also need to clear out the task for Sample from the Start call.
  GetOrCreateTaskRunner()->RunNextTask();

  monitor()->OnTraceLogEnabled();
  GetOrCreateTaskRunner()->RunNextTask();
  ASSERT_TRUE(monitor()->IsEnabledForTesting());
  monitor()->OnTraceLogDisabled();
  ASSERT_FALSE(monitor()->IsEnabledForTesting());
}

}  // namespace trace_event
}  // namespace base
