/*
 * 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 = OatFileAssistant::CalculateCombinedImageChecksum();

  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
