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

#include "common_runtime_test.h"
#include "compiler_callbacks.h"
#include "jit/jit.h"
#include "profile_saver.h"
#include "profile/profile_compilation_info.h"

namespace art HIDDEN {

using Hotness = ProfileCompilationInfo::MethodHotness;

class ProfileSaverTest : public CommonRuntimeTest {
 public:
  void SetUpRuntimeOptions(RuntimeOptions *options) override {
    // Reset the callbacks so that the runtime doesn't think it's for AOT.
    callbacks_ = nullptr;
    CommonRuntimeTest::SetUpRuntimeOptions(options);
    // Enable profile saving and the jit.
    options->push_back(std::make_pair("-Xjitsaveprofilinginfo", nullptr));
    options->push_back(std::make_pair("-Xusejit:true", nullptr));
  }

  void PostRuntimeCreate() override {
    // Create a profile saver.
    Runtime* runtime = Runtime::Current();
    profile_saver_ = new ProfileSaver(
        runtime->GetJITOptions()->GetProfileSaverOptions(),
        runtime->GetJitCodeCache());
  }

  ~ProfileSaverTest() {
    if (profile_saver_ != nullptr) {
      delete profile_saver_;
    }
  }

  ProfileCompilationInfo::ProfileSampleAnnotation GetProfileSampleAnnotation() {
    return profile_saver_->GetProfileSampleAnnotation();
  }

  Hotness::Flag AnnotateSampleFlags(uint32_t flags) {
    return profile_saver_->AnnotateSampleFlags(flags);
  }

 protected:
  ProfileSaver* profile_saver_ = nullptr;
};

// Test profile saving operations for boot image.
class ProfileSaverForBootTest : public ProfileSaverTest {
 public:
  void SetUpRuntimeOptions(RuntimeOptions *options) override {
    ProfileSaverTest::SetUpRuntimeOptions(options);
    options->push_back(std::make_pair("-Xps-profile-boot-class-path", nullptr));
  }
};

TEST_F(ProfileSaverTest, GetProfileSampleAnnotation) {
  ASSERT_EQ(ProfileCompilationInfo::ProfileSampleAnnotation::kNone,
            GetProfileSampleAnnotation());
}

TEST_F(ProfileSaverForBootTest, GetProfileSampleAnnotationUnkown) {
  ProfileCompilationInfo::ProfileSampleAnnotation expected("unknown");
  ASSERT_EQ(expected, GetProfileSampleAnnotation());
}

TEST_F(ProfileSaverForBootTest, GetProfileSampleAnnotation) {
  Runtime::Current()->SetProcessPackageName("test.package");
  ProfileCompilationInfo::ProfileSampleAnnotation expected("test.package");
  ASSERT_EQ(expected, GetProfileSampleAnnotation());
}

TEST_F(ProfileSaverForBootTest, AnnotateSampleFlags) {
  Hotness::Flag expected_flag = Is64BitInstructionSet(Runtime::Current()->GetInstructionSet())
        ? Hotness::kFlag64bit
        : Hotness::kFlag32bit;
  Hotness::Flag actual = AnnotateSampleFlags(Hotness::kFlagHot);

  ASSERT_EQ(static_cast<Hotness::Flag>(expected_flag | Hotness::kFlagHot), actual);
}

TEST_F(ProfileSaverTest, AnnotateSampleFlags) {
  Hotness::Flag actual = AnnotateSampleFlags(Hotness::kFlagHot);

  ASSERT_EQ(Hotness::kFlagHot, actual);
}

}  // namespace art
