/*
 * 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 <string>
#include <vector>

#include <backtrace/BacktraceMap.h>
#include <gtest/gtest.h>

#include "common_runtime_test.h"
#include "compiler_callbacks.h"
#include "dex2oat_environment_test.h"
#include "dexopt_test.h"
#include "gc/space/image_space.h"
#include "mem_map.h"

namespace art {
void DexoptTest::SetUp() {
  ReserveImageSpace();
  Dex2oatEnvironmentTest::SetUp();
}

void DexoptTest::PreRuntimeCreate() {
  std::string error_msg;
  ASSERT_TRUE(PreRelocateImage(GetImageLocation(), &error_msg)) << error_msg;
  ASSERT_TRUE(PreRelocateImage(GetImageLocation2(), &error_msg)) << error_msg;
  UnreserveImageSpace();
}

void DexoptTest::PostRuntimeCreate() {
  ReserveImageSpace();
}

void DexoptTest::GenerateOatForTest(const std::string& dex_location,
                        const std::string& oat_location,
                        CompilerFilter::Filter filter,
                        bool relocate,
                        bool pic,
                        bool with_alternate_image) {
  std::string dalvik_cache = GetDalvikCache(GetInstructionSetString(kRuntimeISA));
  std::string dalvik_cache_tmp = dalvik_cache + ".redirected";

  if (!relocate) {
    // Temporarily redirect the dalvik cache so dex2oat doesn't find the
    // relocated image file.
    ASSERT_EQ(0, rename(dalvik_cache.c_str(), dalvik_cache_tmp.c_str())) << strerror(errno);
  }

  std::vector<std::string> args;
  args.push_back("--dex-file=" + dex_location);
  args.push_back("--oat-file=" + oat_location);
  args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
  args.push_back("--runtime-arg");

  // Use -Xnorelocate regardless of the relocate argument.
  // We control relocation by redirecting the dalvik cache when needed
  // rather than use this flag.
  args.push_back("-Xnorelocate");

  ScratchFile profile_file;
  if (CompilerFilter::DependsOnProfile(filter)) {
    args.push_back("--profile-file=" + profile_file.GetFilename());
  }

  if (pic) {
    args.push_back("--compile-pic");
  }

  std::string image_location = GetImageLocation();
  if (with_alternate_image) {
    args.push_back("--boot-image=" + GetImageLocation2());
  }

  std::string error_msg;
  ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;

  if (!relocate) {
    // Restore the dalvik cache if needed.
    ASSERT_EQ(0, rename(dalvik_cache_tmp.c_str(), dalvik_cache.c_str())) << strerror(errno);
  }

  // Verify the odex file was generated as expected.
  std::unique_ptr<OatFile> odex_file(OatFile::Open(oat_location.c_str(),
                                                   oat_location.c_str(),
                                                   nullptr,
                                                   nullptr,
                                                   false,
                                                   /*low_4gb*/false,
                                                   dex_location.c_str(),
                                                   &error_msg));
  ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
  EXPECT_EQ(pic, odex_file->IsPic());
  EXPECT_EQ(filter, odex_file->GetCompilerFilter());

  std::unique_ptr<ImageHeader> image_header(
          gc::space::ImageSpace::ReadImageHeader(image_location.c_str(),
                                                 kRuntimeISA,
                                                 &error_msg));
  ASSERT_TRUE(image_header != nullptr) << error_msg;
  const OatHeader& oat_header = odex_file->GetOatHeader();
  uint32_t combined_checksum = image_header->GetOatChecksum();

  if (CompilerFilter::DependsOnImageChecksum(filter)) {
    if (with_alternate_image) {
      EXPECT_NE(combined_checksum, oat_header.GetImageFileLocationOatChecksum());
    } else {
      EXPECT_EQ(combined_checksum, oat_header.GetImageFileLocationOatChecksum());
    }
  }

  if (!with_alternate_image) {
    if (CompilerFilter::IsBytecodeCompilationEnabled(filter)) {
      if (relocate) {
        EXPECT_EQ(reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin()),
            oat_header.GetImageFileLocationOatDataBegin());
        EXPECT_EQ(image_header->GetPatchDelta(), oat_header.GetImagePatchDelta());
      } else {
        EXPECT_NE(reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin()),
            oat_header.GetImageFileLocationOatDataBegin());
        EXPECT_NE(image_header->GetPatchDelta(), oat_header.GetImagePatchDelta());
      }
    }
  }
}

void DexoptTest::GenerateOdexForTest(const std::string& dex_location,
                         const std::string& odex_location,
                         CompilerFilter::Filter filter) {
  GenerateOatForTest(dex_location,
                     odex_location,
                     filter,
                     /*relocate*/false,
                     /*pic*/false,
                     /*with_alternate_image*/false);
}

void DexoptTest::GeneratePicOdexForTest(const std::string& dex_location,
                            const std::string& odex_location,
                            CompilerFilter::Filter filter) {
  GenerateOatForTest(dex_location,
                     odex_location,
                     filter,
                     /*relocate*/false,
                     /*pic*/true,
                     /*with_alternate_image*/false);
}

void DexoptTest::GenerateOatForTest(const char* dex_location,
                        CompilerFilter::Filter filter,
                        bool relocate,
                        bool pic,
                        bool with_alternate_image) {
  std::string oat_location;
  std::string error_msg;
  ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename(
        dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg;
  GenerateOatForTest(dex_location,
                     oat_location,
                     filter,
                     relocate,
                     pic,
                     with_alternate_image);
}

void DexoptTest::GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) {
  GenerateOatForTest(dex_location,
                     filter,
                     /*relocate*/true,
                     /*pic*/false,
                     /*with_alternate_image*/false);
}

bool DexoptTest::PreRelocateImage(const std::string& image_location, std::string* error_msg) {
  std::string image;
  if (!GetCachedImageFile(image_location, &image, error_msg)) {
    return false;
  }

  std::string patchoat = GetAndroidRoot();
  patchoat += kIsDebugBuild ? "/bin/patchoatd" : "/bin/patchoat";

  std::vector<std::string> argv;
  argv.push_back(patchoat);
  argv.push_back("--input-image-location=" + image_location);
  argv.push_back("--output-image-file=" + image);
  argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA)));
  argv.push_back("--base-offset-delta=0x00008000");
  return Exec(argv, error_msg);
}

void DexoptTest::ReserveImageSpace() {
  MemMap::Init();

  // Ensure a chunk of memory is reserved for the image space.
  // The reservation_end includes room for the main space that has to come
  // right after the image in case of the GSS collector.
  uintptr_t reservation_start = ART_BASE_ADDRESS;
  uintptr_t reservation_end = ART_BASE_ADDRESS + 384 * MB;

  std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
  ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map";
  for (BacktraceMap::const_iterator it = map->begin();
      reservation_start < reservation_end && it != map->end(); ++it) {
    ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end));
    reservation_start = std::max(reservation_start, it->end);
  }
  ReserveImageSpaceChunk(reservation_start, reservation_end);
}

void DexoptTest::ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) {
  if (start < end) {
    std::string error_msg;
    image_reservation_.push_back(std::unique_ptr<MemMap>(
        MemMap::MapAnonymous("image reservation",
            reinterpret_cast<uint8_t*>(start), end - start,
            PROT_NONE, false, false, &error_msg)));
    ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg;
    LOG(INFO) << "Reserved space for image " <<
      reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" <<
      reinterpret_cast<void*>(image_reservation_.back()->End());
  }
}

void DexoptTest::UnreserveImageSpace() {
  image_reservation_.clear();
}

}  // namespace art
