// 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 "starboard/types.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
