/*
 * Copyright (C) 2021 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 <odr_compilation_log.h>

#include <time.h>

#include <cstdint>
#include <ctime>
#include <iosfwd>
#include <istream>
#include <limits>
#include <ostream>
#include <sstream>
#include <string>
#include <vector>

#include "android-base/file.h"
#include "base/common_art_test.h"
#include "odrefresh/odrefresh.h"
#include "odr_metrics.h"

namespace art {
namespace odrefresh {

const time_t kSecondsPerDay = 86'400;

class OdrCompilationLogTest : public CommonArtTest {};

TEST(OdrCompilationLogEntry, Equality) {
  OdrCompilationLogEntry a{1, 2, 3, 4, 5};

  ASSERT_EQ(a, (OdrCompilationLogEntry{1, 2, 3, 4, 5}));
  ASSERT_NE(a, (OdrCompilationLogEntry{9, 2, 3, 4, 5}));
  ASSERT_NE(a, (OdrCompilationLogEntry{1, 9, 3, 4, 5}));
  ASSERT_NE(a, (OdrCompilationLogEntry{1, 2, 9, 4, 5}));
  ASSERT_NE(a, (OdrCompilationLogEntry{2, 2, 3, 9, 5}));
  ASSERT_NE(a, (OdrCompilationLogEntry{2, 2, 3, 5, 9}));
}

TEST(OdrCompilationLogEntry, InputOutput) {
  const OdrCompilationLogEntry entries[] = {
      {1, 2, 3, 4, 5},
      {std::numeric_limits<int64_t>::min(),
       std::numeric_limits<int64_t>::min(),
       std::numeric_limits<int32_t>::min(),
       std::numeric_limits<time_t>::min(),
       std::numeric_limits<int32_t>::min()},
      {std::numeric_limits<int64_t>::max(),
       std::numeric_limits<int64_t>::max(),
       std::numeric_limits<int32_t>::max(),
       std::numeric_limits<time_t>::max(),
       std::numeric_limits<int32_t>::max()},
       {0, 0, 0, 0, 0},
      {0x7fedcba9'87654321, 0x5a5a5a5a'5a5a5a5a, 0x12345678, 0x2346789, 0x76543210}
  };
  for (const auto& entry : entries) {
    std::stringstream ss;
    ss << entry;
    OdrCompilationLogEntry actual;
    ss >> actual;
    ASSERT_EQ(entry, actual);
  }
}

TEST(OdrCompilationLogEntry, TruncatedInput) {
  std::stringstream ss;
  ss << "1 2";

  OdrCompilationLogEntry entry;
  ss >> entry;

  ASSERT_TRUE(ss.fail());
  ASSERT_FALSE(ss.bad());
}

TEST(OdrCompilationLogEntry, ReadMultiple) {
  std::stringstream ss;
  ss << "0 1 2 3 4\n5 6 7 8 9\n";

  OdrCompilationLogEntry entry0, entry1;
  ss >> entry0 >> entry1;
  ASSERT_EQ(entry0, (OdrCompilationLogEntry{0, 1, 2, 3, 4}));
  ASSERT_EQ(entry1, (OdrCompilationLogEntry{5, 6, 7, 8, 9}));

  ASSERT_FALSE(ss.fail());
  ASSERT_FALSE(ss.bad());
}

TEST(OdrCompilationLog, ShouldAttemptCompile) {
  OdrCompilationLog ocl(/*compilation_log_path=*/nullptr);

  ASSERT_TRUE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, 0));

  ocl.Log(
      /*apex_version=*/1,
      /*last_update_millis=*/762,
      OdrMetrics::Trigger::kApexVersionMismatch,
      ExitCode::kCompilationFailed);
  ASSERT_TRUE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kApexVersionMismatch));
  ASSERT_TRUE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kDexFilesChanged));
  ASSERT_FALSE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown));
}

TEST(OdrCompilationLog, BackOffNoHistory) {
  time_t start_time;
  time(&start_time);

  OdrCompilationLog ocl(/*compilation_log_path=*/nullptr);

  ASSERT_TRUE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time));

  // Start log
  ocl.Log(/*apex_version=*/1,
          /*last_update_millis=*/0,
          OdrMetrics::Trigger::kApexVersionMismatch,
          start_time,
          ExitCode::kCompilationFailed);
  ASSERT_FALSE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time));
  ASSERT_FALSE(
      ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + kSecondsPerDay / 2));
  ASSERT_TRUE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + kSecondsPerDay));

  // Add one more log entry
  ocl.Log(/*apex_version=*/1,
          /*last_update_millis=*/0,
          OdrMetrics::Trigger::kApexVersionMismatch,
          start_time,
          ExitCode::kCompilationFailed);
  ASSERT_FALSE(
      ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + kSecondsPerDay));
  ASSERT_TRUE(
      ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + 2 * kSecondsPerDay));

  // One more.
  ocl.Log(/*apex_version=*/1,
          /*last_update_millis=*/0,
          OdrMetrics::Trigger::kApexVersionMismatch,
          start_time,
          ExitCode::kCompilationFailed);
  ASSERT_FALSE(
      ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + 3 * kSecondsPerDay));
  ASSERT_TRUE(
      ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + 4 * kSecondsPerDay));

  // And one for the road.
  ocl.Log(/*apex_version=*/1,
          /*last_update_millis=*/0,
          OdrMetrics::Trigger::kApexVersionMismatch,
          start_time,
          ExitCode::kCompilationFailed);
  ASSERT_FALSE(
      ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + 7 * kSecondsPerDay));
  ASSERT_TRUE(
      ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + 8 * kSecondsPerDay));
}

TEST(OdrCompilationLog, BackOffHappyHistory) {
  time_t start_time;
  time(&start_time);

  OdrCompilationLog ocl(/*compilation_log_path=*/nullptr);

  // Start log with a successful entry.
  ocl.Log(/*apex_version=*/1,
          /*last_update_millis=*/0,
          OdrMetrics::Trigger::kApexVersionMismatch,
          start_time,
          ExitCode::kCompilationSuccess);
  ASSERT_TRUE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time));
  ASSERT_TRUE(
      ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + kSecondsPerDay / 4));
  ASSERT_TRUE(
      ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + kSecondsPerDay / 2));

  // Add a log entry for a failed compilation.
  ocl.Log(/*apex_version=*/1,
          /*last_update_millis=*/0,
          OdrMetrics::Trigger::kApexVersionMismatch,
          start_time,
          ExitCode::kCompilationFailed);
  ASSERT_FALSE(
      ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + kSecondsPerDay / 2));
  ASSERT_TRUE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + kSecondsPerDay));
}

TEST_F(OdrCompilationLogTest, LogNumberOfEntriesAndPeek) {
  OdrCompilationLog ocl(/*compilation_log_path=*/nullptr);

  std::vector<OdrCompilationLogEntry> entries = {
    { 0, 1, 2, 3, 4 },
    { 1, 2, 3, 4, 5 },
    { 2, 3, 4, 5, 6 },
    { 3, 4, 5, 6, 7 },
    { 4, 5, 6, 7, 8 },
    { 5, 6, 7, 8, 9 },
    { 6, 7, 8, 9, 10 }
  };

  for (size_t i = 0; i < entries.size(); ++i) {
    OdrCompilationLogEntry& e = entries[i];
    ocl.Log(e.apex_version,
            e.last_update_millis,
            static_cast<OdrMetrics::Trigger>(e.trigger),
            e.when,
            static_cast<ExitCode>(e.exit_code));
    if (i < OdrCompilationLog::kMaxLoggedEntries) {
      ASSERT_EQ(i + 1, ocl.NumberOfEntries());
    } else {
      ASSERT_EQ(OdrCompilationLog::kMaxLoggedEntries, ocl.NumberOfEntries());
    }

    for (size_t j = 0; j < ocl.NumberOfEntries(); ++j) {
      const OdrCompilationLogEntry* logged = ocl.Peek(j);
      ASSERT_TRUE(logged != nullptr);
      const OdrCompilationLogEntry& expected = entries[i + 1 - ocl.NumberOfEntries() + j];
      ASSERT_EQ(expected, *logged);
    }
  }
}

TEST_F(OdrCompilationLogTest, LogReadWrite) {
  std::vector<OdrCompilationLogEntry> entries = {
    { 0, 1, 2, 3, 4 },
    { 1, 2, 3, 4, 5 },
    { 2, 3, 4, 5, 6 },
    { 3, 4, 5, 6, 7 },
    { 4, 5, 6, 7, 8 },
    { 5, 6, 7, 8, 9 },
    { 6, 7, 8, 9, 10 }
  };

  ScratchFile scratch_file;
  scratch_file.Close();

  for (size_t i = 0; i < entries.size(); ++i) {
    {
      OdrCompilationLog ocl(scratch_file.GetFilename().c_str());
      OdrCompilationLogEntry& e = entries[i];
      ocl.Log(e.apex_version,
              e.last_update_millis,
              static_cast<OdrMetrics::Trigger>(e.trigger),
              e.when,
              static_cast<ExitCode>(e.exit_code));
    }

    {
      OdrCompilationLog ocl(scratch_file.GetFilename().c_str());
      if (i < OdrCompilationLog::kMaxLoggedEntries) {
        ASSERT_EQ(i + 1, ocl.NumberOfEntries());
      } else {
        ASSERT_EQ(OdrCompilationLog::kMaxLoggedEntries, ocl.NumberOfEntries());
      }

      for (size_t j = 0; j < ocl.NumberOfEntries(); ++j) {
        const OdrCompilationLogEntry* logged = ocl.Peek(j);
        ASSERT_TRUE(logged != nullptr);
        const OdrCompilationLogEntry& expected = entries[i + 1 - ocl.NumberOfEntries() + j];
        ASSERT_EQ(expected, *logged);
      }
    }
  }
}

TEST_F(OdrCompilationLogTest, BackoffBasedOnLog) {
  time_t start_time;
  time(&start_time);

  ScratchFile scratch_file;
  scratch_file.Close();

  const char* log_path = scratch_file.GetFilename().c_str();
  {
    OdrCompilationLog ocl(log_path);

    ASSERT_TRUE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time));
  }

  {
    OdrCompilationLog ocl(log_path);

    // Start log
    ocl.Log(/*apex_version=*/1,
            /*last_update_millis=*/0,
            OdrMetrics::Trigger::kApexVersionMismatch,
            start_time,
            ExitCode::kCompilationFailed);
  }

  {
    OdrCompilationLog ocl(log_path);
    ASSERT_FALSE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time));
    ASSERT_FALSE(
        ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + kSecondsPerDay / 2));
    ASSERT_TRUE(
        ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + kSecondsPerDay));
  }

  {
    // Add one more log entry
    OdrCompilationLog ocl(log_path);
    ocl.Log(/*apex_version=*/1,
            /*last_update_millis=*/0,
            OdrMetrics::Trigger::kApexVersionMismatch,
            start_time,
            ExitCode::kCompilationFailed);
  }

  {
    OdrCompilationLog ocl(log_path);

    ASSERT_FALSE(
        ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + kSecondsPerDay));
    ASSERT_TRUE(
        ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + 2 * kSecondsPerDay));
  }

  {
    // One more log entry.
    OdrCompilationLog ocl(log_path);
    ocl.Log(/*apex_version=*/1,
            /*last_update_millis=*/0,
            OdrMetrics::Trigger::kApexVersionMismatch,
            start_time,
            ExitCode::kCompilationFailed);
  }

  {
    OdrCompilationLog ocl(log_path);
    ASSERT_FALSE(
        ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + 3 * kSecondsPerDay));
    ASSERT_TRUE(
        ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + 4 * kSecondsPerDay));
  }

  {
    // And one for the road.
    OdrCompilationLog ocl(log_path);
    ocl.Log(/*apex_version=*/1,
            /*last_update_millis=*/0,
            OdrMetrics::Trigger::kApexVersionMismatch,
            start_time,
            ExitCode::kCompilationFailed);
  }

  {
    OdrCompilationLog ocl(log_path);
    ASSERT_FALSE(
        ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + 7 * kSecondsPerDay));
    ASSERT_TRUE(
        ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time + 8 * kSecondsPerDay));
  }
}

TEST_F(OdrCompilationLogTest, NewLogVersionTriggersCompilation) {
  static const int64_t kApexVersion = 1066;
  static const int64_t kLastUpdateMillis = 777;
  time_t start_time;
  time(&start_time);

  ScratchFile scratch_file;
  scratch_file.Close();

  // Generate a compilation log.
  {
    OdrCompilationLog ocl(scratch_file.GetFilename().c_str());
    for (size_t i = 0; i < OdrCompilationLog::kMaxLoggedEntries; ++i) {
      ocl.Log(kApexVersion,
              kLastUpdateMillis,
              OdrMetrics::Trigger::kApexVersionMismatch,
              start_time,
              ExitCode::kCompilationFailed);
      ASSERT_FALSE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time));
    }
  }

  // Replace version string in the compilation log.
  std::string log_text;
  ASSERT_TRUE(android::base::ReadFileToString(scratch_file.GetFilename(), &log_text));
  std::string new_log_version = std::string(OdrCompilationLog::kLogVersion) + "a";
  log_text.replace(0, new_log_version.size() - 1, new_log_version);
  ASSERT_TRUE(android::base::WriteStringToFile(log_text, scratch_file.GetFilename()));

  // Read log with updated version entry, check it is treated as out-of-date.
  {
    OdrCompilationLog ocl(scratch_file.GetFilename().c_str());
    ASSERT_TRUE(ocl.ShouldAttemptCompile(OdrMetrics::Trigger::kUnknown, start_time));
    ASSERT_EQ(0u, ocl.NumberOfEntries());
  }
}

}  // namespace odrefresh
}  // namespace art
