/*
 * 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 <fstream>

#include "android-base/strings.h"

#include "base/unix_file/fd_file.h"
#include "base/zip_archive.h"
#include "common_runtime_test.h"
#include "dex/art_dex_file_loader.h"
#include "dex/class_accessor-inl.h"
#include "dex/dex_file-inl.h"
#include "exec_utils.h"

namespace art {

class HiddenApiTest : public CommonRuntimeTest {
 protected:
  std::string GetHiddenApiCmd() {
    std::string file_path = GetArtBinDir() + "/hiddenapi";
    if (kIsDebugBuild) {
      file_path += 'd';
    }
    if (!OS::FileExists(file_path.c_str())) {
      LOG(FATAL) << "Could not find binary " << file_path;
      UNREACHABLE();
    }
    return file_path;
  }

  std::unique_ptr<const DexFile> RunHiddenapiEncode(const ScratchFile& flags_csv,
                                                    const std::vector<std::string>& extra_args,
                                                    const ScratchFile& out_dex) {
    std::string error;
    ScratchFile in_dex;
    std::unique_ptr<ZipArchive> jar(
        ZipArchive::Open(GetTestDexFileName("HiddenApi").c_str(), &error));
    if (jar == nullptr) {
      LOG(FATAL) << "Could not open test file " << GetTestDexFileName("HiddenApi") << ": " << error;
      UNREACHABLE();
    }
    std::unique_ptr<ZipEntry> jar_classes_dex(jar->Find("classes.dex", &error));
    if (jar_classes_dex == nullptr) {
      LOG(FATAL) << "Could not find classes.dex in test file " << GetTestDexFileName("HiddenApi")
                 << ": " << error;
      UNREACHABLE();
    } else if (!jar_classes_dex->ExtractToFile(*in_dex.GetFile(), &error)) {
      LOG(FATAL) << "Could not extract classes.dex from test file "
                 << GetTestDexFileName("HiddenApi") << ": " << error;
      UNREACHABLE();
    }

    std::vector<std::string> argv_str;
    argv_str.push_back(GetHiddenApiCmd());
    argv_str.insert(argv_str.end(), extra_args.begin(), extra_args.end());
    argv_str.push_back("encode");
    argv_str.push_back("--input-dex=" + in_dex.GetFilename());
    argv_str.push_back("--output-dex=" + out_dex.GetFilename());
    argv_str.push_back("--api-flags=" + flags_csv.GetFilename());
    argv_str.push_back("--no-force-assign-all");
    int return_code = ExecAndReturnCode(argv_str, &error);
    if (return_code == 0) {
      return OpenDex(out_dex);
    } else {
      LOG(ERROR) << "HiddenApi binary exited with unexpected return code " << return_code;
      return nullptr;
    }
  }

  bool RunHiddenapiList(const ScratchFile& out_flags_csv) {
    std::string error;
    std::string boot_jar = GetTestDexFileName("HiddenApi");
    std::string stub_jar = GetTestDexFileName("HiddenApiStubs");
    std::string boot_cp = android::base::Join(GetLibCoreDexFileNames(), ":");

    std::vector<std::string> argv_str;
    argv_str.push_back(GetHiddenApiCmd());
    argv_str.push_back("list");
    for (const std::string& core_jar : GetLibCoreDexFileNames()) {
      argv_str.push_back("--boot-dex=" + core_jar);
    }
    argv_str.push_back("--boot-dex=" + boot_jar);
    argv_str.push_back("--public-stub-classpath=" + boot_cp + ":" + stub_jar);
    argv_str.push_back("--out-api-flags=" + out_flags_csv.GetFilename());
    int return_code = ExecAndReturnCode(argv_str, &error);
    if (return_code == 0) {
      return true;
    } else {
      LOG(ERROR) << "HiddenApi binary exited with unexpected return code " << return_code;
      return false;
    }
  }

  std::unique_ptr<const DexFile> OpenDex(const ScratchFile& file) {
    ArtDexFileLoader dex_loader;
    std::string error_msg;

    File fd(file.GetFilename(), O_RDONLY, /* check_usage= */ false);
    if (fd.Fd() == -1) {
      PLOG(FATAL) << "Unable to open file '" << file.GetFilename() << "'";
      UNREACHABLE();
    }

    std::unique_ptr<const DexFile> dex_file(dex_loader.OpenDex(
        fd.Release(), /* location= */ file.GetFilename(), /* verify= */ true,
        /* verify_checksum= */ true, /* mmap_shared= */ false, &error_msg));
    if (dex_file.get() == nullptr) {
      LOG(FATAL) << "Open failed for '" << file.GetFilename() << "' " << error_msg;
      UNREACHABLE();
    } else if (!dex_file->IsStandardDexFile()) {
      LOG(FATAL) << "Expected a standard dex file '" << file.GetFilename() << "'";
      UNREACHABLE();
    }

    return dex_file;
  }

  std::ofstream OpenStream(const ScratchFile& file) {
    std::ofstream ofs(file.GetFilename(), std::ofstream::out);
    if (ofs.fail()) {
      PLOG(FATAL) << "Open failed for '" << file.GetFilename() << "'";
      UNREACHABLE();
    }
    return ofs;
  }

  std::map<std::string, std::string> ReadFlagsCsvFile(const ScratchFile& file) {
    std::ifstream ifs(file.GetFilename());
    std::map<std::string, std::string> flags;

    for (std::string line; std::getline(ifs, line);) {
      std::size_t comma = line.find(",");
      if (comma == std::string::npos) {
        flags.emplace(line, "");
      } else {
        flags.emplace(line.substr(0, comma), line.substr(comma + 1));
      }
    }

    return flags;
  }

  std::string SafeMapGet(const std::string& key, const std::map<std::string, std::string>& map) {
    auto it = map.find(key);
    if (it == map.end()) {
      LOG(FATAL) << "Key not found: " << key;
      UNREACHABLE();
    }
    return it->second;
  }

  const dex::ClassDef& FindClass(const char* desc, const DexFile& dex_file) {
    const dex::TypeId* type_id = dex_file.FindTypeId(desc);
    CHECK(type_id != nullptr) << "Could not find class " << desc;
    const dex::ClassDef* found = dex_file.FindClassDef(dex_file.GetIndexForTypeId(*type_id));
    CHECK(found != nullptr) << "Could not find class " << desc;
    return *found;
  }

  hiddenapi::ApiList GetFieldHiddenFlags(const char* name,
                                         uint32_t expected_visibility,
                                         const dex::ClassDef& class_def,
                                         const DexFile& dex_file) {
    ClassAccessor accessor(dex_file, class_def, /* parse hiddenapi flags */ true);
    CHECK(accessor.HasClassData()) << "Class " << accessor.GetDescriptor() << " has no data";

    if (!accessor.HasHiddenapiClassData()) {
      return hiddenapi::ApiList::Whitelist();
    }

    for (const ClassAccessor::Field& field : accessor.GetFields()) {
      const dex::FieldId& fid = dex_file.GetFieldId(field.GetIndex());
      if (strcmp(name, dex_file.GetFieldName(fid)) == 0) {
        const uint32_t actual_visibility = field.GetAccessFlags() & kAccVisibilityFlags;
        CHECK_EQ(actual_visibility, expected_visibility)
            << "Field " << name << " in class " << accessor.GetDescriptor();
        return hiddenapi::ApiList(field.GetHiddenapiFlags());
      }
    }

    LOG(FATAL) << "Could not find field " << name << " in class "
               << dex_file.GetClassDescriptor(class_def);
    UNREACHABLE();
  }

  hiddenapi::ApiList GetMethodHiddenFlags(const char* name,
                                          uint32_t expected_visibility,
                                          bool expected_native,
                                          const dex::ClassDef& class_def,
                                          const DexFile& dex_file) {
    ClassAccessor accessor(dex_file, class_def, /* parse hiddenapi flags */ true);
    CHECK(accessor.HasClassData()) << "Class " << accessor.GetDescriptor() << " has no data";

    if (!accessor.HasHiddenapiClassData()) {
      return hiddenapi::ApiList::Whitelist();
    }

    for (const ClassAccessor::Method& method : accessor.GetMethods()) {
      const dex::MethodId& mid = dex_file.GetMethodId(method.GetIndex());
      if (strcmp(name, dex_file.GetMethodName(mid)) == 0) {
        CHECK_EQ(expected_native, method.MemberIsNative())
            << "Method " << name << " in class " << accessor.GetDescriptor();
        const uint32_t actual_visibility = method.GetAccessFlags() & kAccVisibilityFlags;
        CHECK_EQ(actual_visibility, expected_visibility)
            << "Method " << name << " in class " << accessor.GetDescriptor();
        return hiddenapi::ApiList(method.GetHiddenapiFlags());
      }
    }

    LOG(FATAL) << "Could not find method " << name << " in class "
               << dex_file.GetClassDescriptor(class_def);
    UNREACHABLE();
  }

  hiddenapi::ApiList GetIFieldHiddenFlags(const DexFile& dex_file) {
    return GetFieldHiddenFlags("ifield", kAccPublic, FindClass("LMain;", dex_file), dex_file);
  }

  hiddenapi::ApiList GetSFieldHiddenFlags(const DexFile& dex_file) {
    return GetFieldHiddenFlags("sfield", kAccPrivate, FindClass("LMain;", dex_file), dex_file);
  }

  hiddenapi::ApiList GetIMethodHiddenFlags(const DexFile& dex_file) {
    return GetMethodHiddenFlags(
        "imethod", 0, /* expected_native= */ false, FindClass("LMain;", dex_file), dex_file);
  }

  hiddenapi::ApiList GetSMethodHiddenFlags(const DexFile& dex_file) {
    return GetMethodHiddenFlags("smethod",
                                kAccPublic,
                                /* expected_native= */ false,
                                FindClass("LMain;", dex_file),
                                dex_file);
  }

  hiddenapi::ApiList GetINMethodHiddenFlags(const DexFile& dex_file) {
    return GetMethodHiddenFlags("inmethod",
                                kAccPublic,
                                /* expected_native= */ true,
                                FindClass("LMain;", dex_file),
                                dex_file);
  }

  hiddenapi::ApiList GetSNMethodHiddenFlags(const DexFile& dex_file) {
    return GetMethodHiddenFlags("snmethod",
                                kAccProtected,
                                /* expected_native= */ true,
                                FindClass("LMain;", dex_file),
                                dex_file);
  }
};

TEST_F(HiddenApiTest, InstanceFieldNoMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->ifield:LBadType1;,greylist" << std::endl
      << "LMain;->ifield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->ifield:LBadType3;,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetIFieldHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceFieldLightGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->ifield:I,greylist" << std::endl
      << "LMain;->ifield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->ifield:LBadType3;,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetIFieldHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceFieldDarkGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->ifield:LBadType1;,greylist" << std::endl
      << "LMain;->ifield:I,greylist-max-o" << std::endl
      << "LMain;->ifield:LBadType3;,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetIFieldHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceFieldBlacklistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->ifield:LBadType1;,greylist" << std::endl
      << "LMain;->ifield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->ifield:I,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetIFieldHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceFieldTwoListsMatch1) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->ifield:LBadType1;,greylist" << std::endl
      << "LMain;->ifield:I,blacklist,greylist-max-o" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, InstanceFieldTwoListsMatch2) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->ifield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->ifield:I,blacklist,greylist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, InstanceFieldTwoListsMatch3) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->ifield:I,greylist,greylist-max-o" << std::endl
      << "LMain;->ifield:LBadType3;,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, StaticFieldNoMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->sfield:LBadType1;,greylist" << std::endl
      << "LMain;->sfield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->sfield:LBadType3;,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetSFieldHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticFieldLightGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->sfield:Ljava/lang/Object;,greylist" << std::endl
      << "LMain;->sfield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->sfield:LBadType3;,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetSFieldHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticFieldDarkGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->sfield:LBadType1;,greylist" << std::endl
      << "LMain;->sfield:Ljava/lang/Object;,greylist-max-o" << std::endl
      << "LMain;->sfield:LBadType3;,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetSFieldHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticFieldBlacklistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->sfield:LBadType1;,greylist" << std::endl
      << "LMain;->sfield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->sfield:Ljava/lang/Object;,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetSFieldHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticFieldTwoListsMatch1) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->sfield:LBadType1;,greylist" << std::endl
      << "LMain;->sfield:Ljava/lang/Object;,blacklist,greylist-max-o" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, StaticFieldTwoListsMatch2) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->sfield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->sfield:Ljava/lang/Object;,blacklist,greylist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, StaticFieldTwoListsMatch3) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->sfield:Ljava/lang/Object;,greylist,greylist-max-o" << std::endl
      << "LMain;->sfield:LBadType3;,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, InstanceMethodNoMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->imethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->imethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->imethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetIMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceMethodLightGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->imethod(J)V,greylist" << std::endl
      << "LMain;->imethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->imethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetIMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceMethodDarkGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->imethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->imethod(J)V,greylist-max-o" << std::endl
      << "LMain;->imethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetIMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceMethodBlacklistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->imethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->imethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->imethod(J)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetIMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceMethodTwoListsMatch1) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->imethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->imethod(J)V,blacklist,greylist-max-o" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, InstanceMethodTwoListsMatch2) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->imethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->imethod(J)V,blacklist,greylist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, InstanceMethodTwoListsMatch3) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->imethod(J)V,greylist,greylist-max-o" << std::endl
      << "LMain;->imethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, StaticMethodNoMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->smethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->smethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->smethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetSMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticMethodLightGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->smethod(Ljava/lang/Object;)V,greylist" << std::endl
      << "LMain;->smethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->smethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetSMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticMethodDarkGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->smethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->smethod(Ljava/lang/Object;)V,greylist-max-o" << std::endl
      << "LMain;->smethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetSMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticMethodBlacklistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->smethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->smethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->smethod(Ljava/lang/Object;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetSMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticMethodTwoListsMatch1) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->smethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->smethod(Ljava/lang/Object;)V,blacklist,greylist-max-o" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, StaticMethodTwoListsMatch2) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->smethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->smethod(Ljava/lang/Object;)V,blacklist,greylist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, StaticMethodTwoListsMatch3) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->smethod(Ljava/lang/Object;)V,greylist,greylist-max-o" << std::endl
      << "LMain;->smethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, InstanceNativeMethodNoMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->inmethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->inmethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->inmethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetINMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceNativeMethodLightGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->inmethod(C)V,greylist" << std::endl
      << "LMain;->inmethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->inmethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetINMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceNativeMethodDarkGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->inmethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->inmethod(C)V,greylist-max-o" << std::endl
      << "LMain;->inmethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetINMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceNativeMethodBlacklistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->inmethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->inmethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->inmethod(C)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetINMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceNativeMethodTwoListsMatch1) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->inmethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->inmethod(C)V,blacklist,greylist-max-o" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, InstanceNativeMethodTwoListsMatch2) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->inmethod(C)V,blacklist,greylist" << std::endl
      << "LMain;->inmethod(LBadType2;)V,greylist-max-o" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, InstanceNativeMethodTwoListsMatch3) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->inmethod(C)V,greylist,greylist-max-o" << std::endl
      << "LMain;->inmethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, StaticNativeMethodNoMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->snmethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->snmethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->snmethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Whitelist(), GetSNMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticNativeMethodLightGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->snmethod(Ljava/lang/Integer;)V,greylist" << std::endl
      << "LMain;->snmethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->snmethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Greylist(), GetSNMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticNativeMethodDarkGreylistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->snmethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->snmethod(Ljava/lang/Integer;)V,greylist-max-o" << std::endl
      << "LMain;->snmethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::GreylistMaxO(), GetSNMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticNativeMethodBlacklistMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->snmethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->snmethod(LBadType2;)V,greylist-max-o" << std::endl
      << "LMain;->snmethod(Ljava/lang/Integer;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::Blacklist(), GetSNMethodHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, StaticNativeMethodTwoListsMatch1) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->snmethod(LBadType1;)V,greylist" << std::endl
      << "LMain;->snmethod(Ljava/lang/Integer;)V,blacklist,greylist-max-o" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, StaticNativeMethodTwoListsMatch2) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->snmethod(Ljava/lang/Integer;)V,blacklist,greylist" << std::endl
      << "LMain;->snmethod(LBadType2;)V,greylist-max-o" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, StaticNativeMethodTwoListsMatch3) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->snmethod(Ljava/lang/Integer;)V,greylist,greylist-max-o" << std::endl
      << "LMain;->snmethod(LBadType3;)V,blacklist" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

TEST_F(HiddenApiTest, InstanceFieldCorePlatformApiMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->ifield:LBadType1;,greylist" << std::endl
      << "LMain;->ifield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->ifield:I,greylist,core-platform-api" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::CorePlatformApi() |
  hiddenapi::ApiList::Greylist(), GetIFieldHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceFieldTestApiMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->ifield:LBadType1;,greylist" << std::endl
      << "LMain;->ifield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->ifield:I,greylist,test-api" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_NE(dex_file.get(), nullptr);
  ASSERT_EQ(hiddenapi::ApiList::TestApi()
  | hiddenapi::ApiList::Greylist(), GetIFieldHiddenFlags(*dex_file));
}

TEST_F(HiddenApiTest, InstanceFieldUnknownFlagMatch) {
  ScratchFile dex, flags_csv;
  OpenStream(flags_csv)
      << "LMain;->ifield:LBadType1;,greylist" << std::endl
      << "LMain;->ifield:LBadType2;,greylist-max-o" << std::endl
      << "LMain;->ifield:I,greylist,unknown-flag" << std::endl;
  auto dex_file = RunHiddenapiEncode(flags_csv, {}, dex);
  ASSERT_EQ(dex_file.get(), nullptr);
}

// The following tests use this class hierarchy:
//
//    AbstractPackageClass  PublicInterface
//           |                     |
//           |    ┌----------------┘
//           |    |
//        PackageClass
//
// Only PublicInterface is in stubs.

// Test a method declared in PublicInterface and defined in PackageClass.
TEST_F(HiddenApiTest, InterfaceMethodImplemented) {
  ScratchFile flags_csv;
  ASSERT_TRUE(RunHiddenapiList(flags_csv));
  auto flags = ReadFlagsCsvFile(flags_csv);
  ASSERT_EQ(SafeMapGet("LPackageClass;->publicMethod1()V", flags), "public-api");
}

// Test a method declared in PublicInterface, defined in AbstractPackageClass and
// inherited by PackageClass.
TEST_F(HiddenApiTest, InterfaceMethodImplementedInParent) {
  ScratchFile flags_csv;
  ASSERT_TRUE(RunHiddenapiList(flags_csv));
  auto flags = ReadFlagsCsvFile(flags_csv);
  ASSERT_EQ(SafeMapGet("LAbstractPackageClass;->publicMethod2()V", flags), "public-api");
}

}  // namespace art
