/*
 * 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 "dex2oat_options.h"

#include <memory>

#include "cmdline_parser.h"
#include "driver/compiler_options_map-inl.h"

namespace art {

template<>
struct CmdlineType<InstructionSet> : CmdlineTypeParser<InstructionSet> {
  Result Parse(const std::string& option) {
    InstructionSet set = GetInstructionSetFromString(option.c_str());
    if (set == InstructionSet::kNone) {
      return Result::Failure(std::string("Not a valid instruction set: '") + option + "'");
    }
    return Result::Success(set);
  }

  static const char* Name() { return "InstructionSet"; }
  static const char* DescribeType() { return "arm|arm64|x86|x86_64|none"; }
};

#define COMPILER_OPTIONS_MAP_TYPE Dex2oatArgumentMap
#define COMPILER_OPTIONS_MAP_KEY_TYPE Dex2oatArgumentMapKey
#include "driver/compiler_options_map-storage.h"

// Specify storage for the Dex2oatOptions keys.

#define DEX2OAT_OPTIONS_KEY(Type, Name, ...) \
  const Dex2oatArgumentMap::Key<Type> Dex2oatArgumentMap::Name {__VA_ARGS__};
#include "dex2oat_options.def"

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wframe-larger-than="

using M = Dex2oatArgumentMap;
using Parser = CmdlineParser<Dex2oatArgumentMap, Dex2oatArgumentMap::Key>;
using Builder = Parser::Builder;

static void AddInputMappings(Builder& builder) {
  // clang-format off
  builder.
      Define("--dex-file=_")
          .WithType<std::vector<std::string>>().AppendValues()
          .WithHelp("Specifies a .dex, .jar, or .apk file to compile.\n"
                    "Eg: --dex-file=/system/framework/core.jar")
          .WithMetavar("<dex-file>")
          .IntoKey(M::DexFiles)
      .Define("--dex-location=_")
          .WithType<std::vector<std::string>>().AppendValues()
          .WithMetavar("<dex-location>")
          .WithHelp("specifies an alternative dex location to encode in the oat file for the\n"
                    "corresponding --dex-file argument. The first --dex-location corresponds to\n"
                    "the first --dex-file, the second to the second and so on.\n"
                    "Eg: --dex-file=/home/build/out/system/framework/core.jar\n"
                    "    --dex-location=/system/framework/core.jar")
          .IntoKey(M::DexLocations)
      .Define("--dex-fd=_")
          .WithType<std::vector<int>>().AppendValues()
          .WithHelp("Specifies a file descriptor of a dex file. It can be specified for multiple\n"
                    "times, but the number must match the number of --dex-file. Eg: --dex-fd=5")
          .IntoKey(M::DexFds)
      .Define("--zip-fd=_")
          .WithType<int>()
          .WithHelp("specifies a file descriptor of a zip file containing a classes.dex file to\n"
                    "compile. Eg: --zip-fd=5")
          .IntoKey(M::ZipFd)
      .Define("--zip-location=_")
          .WithType<std::string>()
          .WithHelp("Specifies a symbolic name for the file corresponding to the FD given by\n"
                    "--zip-fd.")
          .IntoKey(M::ZipLocation)
      .Define("--boot-image=_")
          .WithType<std::string>()
          .WithHelp("provide the image file for the boot class path.\n"
                    "Do not include the arch as part of the name, it is added automatically.\n"
                    "Example: --boot-image=/system/framework/boot.art\n"
                    "         (specifies /system/framework/<arch>/boot.art as the image file)\n"
                    "Example: --boot-image=boot.art:boot-framework.art\n"
                    "         (specifies <bcp-path1>/<arch>/boot.art as the image file and\n"
                    "         <bcp-path2>/<arch>/boot-framework.art as the image extension file\n"
                    "         with paths taken from corresponding boot class path components)\n"
                    "Example: --boot-image=/apex/com.android.art/boot.art:/system/framework/*:*\n"
                    "         (specifies /apex/com.android.art/<arch>/boot.art as the image\n"
                    "         file and search for extensions in /framework/system and boot\n"
                    "         class path components' paths)\n"
                    "Default: $ANDROID_ROOT/system/framework/boot.art")
          .IntoKey(M::BootImage);
  // clang-format on
}

static void AddGeneratedArtifactMappings(Builder& builder) {
  // clang-format off
  builder.
      Define("--input-vdex-fd=_")
          .WithType<int>()
          .WithHelp("specifies the vdex input source via a file descriptor.")
          .IntoKey(M::InputVdexFd)
      .Define("--input-vdex=_")
          .WithType<std::string>()
          .WithHelp("specifies the vdex input source via a filename.")
          .IntoKey(M::InputVdex)
      .Define("--output-vdex-fd=_")
          .WithHelp("specifies the vdex output destination via a file descriptor.")
          .WithType<int>()
          .IntoKey(M::OutputVdexFd)
      .Define("--output-vdex=_")
          .WithType<std::string>()
          .WithHelp("specifies the vdex output destination via a filename.")
          .IntoKey(M::OutputVdex)
      .Define("--dm-fd=_")
          .WithType<int>()
          .WithHelp("specifies the dm output destination via a file descriptor.")
          .IntoKey(M::DmFd)
      .Define("--dm-file=_")
          .WithType<std::string>()
          .WithHelp("specifies the dm output destination via a filename.")
          .IntoKey(M::DmFile)
      .Define("--oat-file=_")
          .WithType<std::string>()
          .WithHelp(" Specifies an oat output destination via a filename.\n"
                    "Eg: --oat-file=/system/framework/boot.oat")
          .IntoKey(M::OatFile)
      .Define("--oat-symbols=_")
          .WithType<std::string>()
          .WithHelp("Specifies a symbolized oat output destination.\n"
                    "Eg: --oat-symbols=symbols/system/framework/boot.oat")
          .IntoKey(M::OatSymbols)
      .Define("--strip")
          .WithHelp("remove all debugging sections at the end (but keep mini-debug-info).\n"
                    "This is equivalent to the \"strip\" command as build post-processing step.\n"
                    "It is intended to be used with --oat-symbols and it happens after it.\n"
                    "Eg: --oat-symbols=/symbols/system/framework/boot.oat")
          .IntoKey(M::Strip)
      .Define("--oat-fd=_")
          .WithType<int>()
          .WithHelp("Specifies the oat output destination via a file descriptor. Eg: --oat-fd=5")
          .IntoKey(M::OatFd)
      .Define("--oat-location=_")
          .WithType<std::string>()
          .WithHelp("specifies a symbolic name for the file corresponding to the file descriptor\n"
                    "specified by --oat-fd.\n"
                    "Eg: --oat-location=/data/dalvik-cache/system@app@Calculator.apk.oat")
          .IntoKey(M::OatLocation);
  // clang-format on
}

static void AddImageMappings(Builder& builder) {
  // clang-format off
  builder.
      Define("--image=_")
          .WithType<std::string>()
          .WithHelp("specifies an output image filename. Eg: --image=/system/framework/boot.art")
          .IntoKey(M::ImageFilename)
      .Define("--image-fd=_")
          .WithType<int>()
          .WithHelp("specifies an output image file descriptor. Cannot be used with --image.\n"
                    "Eg: --image-fd=7")
          .IntoKey(M::ImageFd)
      .Define("--base=_")
          .WithType<std::string>()
          .WithHelp("Specifies the base address when creating a boot image. Eg: --base=0x50000000")
          .WithMetavar("{hex address}")
          .IntoKey(M::Base)
      .Define("--app-image-file=_")
          .WithType<std::string>()
          .WithHelp("Specify a file name for app image. Only used if a profile is passed in.")
          .IntoKey(M::AppImageFile)
      .Define("--app-image-fd=_")
          .WithType<int>()
          .WithHelp("Specify a file descriptor for app image. Only used if a profile is passed in.")
          .IntoKey(M::AppImageFileFd)
      .Define({"--multi-image", "--single-image"})
          .WithValues({true, false})
          .WithHelp("Specifies if separate oat and image files should be generated for each dex\n"
                    "file. --multi-image is default for boot image and --single-image for app\n"
                    "images.")
          .IntoKey(M::MultiImage)
      .Define("--dirty-image-objects=_")
          .WithType<std::string>()
          .WithHelp("list of known dirty objects in the image. The image writer will group them"
                    " together")
          .IntoKey(M::DirtyImageObjects)
      .Define("--dirty-image-objects-fd=_")
          .WithType<int>()
          .WithHelp("Specify a file descriptor for reading the list of known dirty objects in\n"
                    "the image. The image writer will group them together")
          .IntoKey(M::DirtyImageObjectsFd)
      .Define("--updatable-bcp-packages-file=_")
          .WithType<std::string>()
          .WithHelp("Deprecated. No longer takes effect.")
          .IntoKey(M::UpdatableBcpPackagesFile)
      .Define("--updatable-bcp-packages-fd=_")
          .WithType<int>()
          .WithHelp("Deprecated. No longer takes effect.")
          .IntoKey(M::UpdatableBcpPackagesFd)
      .Define("--image-format=_")
          .WithType<ImageHeader::StorageMode>()
          .WithValueMap({{"lz4", ImageHeader::kStorageModeLZ4},
                         {"lz4hc", ImageHeader::kStorageModeLZ4HC},
                         {"uncompressed", ImageHeader::kStorageModeUncompressed}})
          .WithHelp("Which format to store the image Defaults to uncompressed. Eg:"
                    " --image-format=lz4")
          .IntoKey(M::ImageFormat);
  // clang-format on
}

static void AddSwapMappings(Builder& builder) {
  // clang-format off
  builder.
      Define("--swap-file=_")
          .WithType<std::string>()
          .WithHelp("Specify a file to use for swap. Eg: --swap-file=/data/tmp/swap.001")
          .IntoKey(M::SwapFile)
      .Define("--swap-fd=_")
          .WithType<int>()
          .WithHelp("Specify a file to use for swap by file-descriptor. Eg: --swap-fd=3")
          .IntoKey(M::SwapFileFd)
      .Define("--swap-dex-size-threshold=_")
          .WithType<unsigned int>()
          .WithHelp("specifies the minimum total dex file size in bytes to allow the use of swap.")
          .IntoKey(M::SwapDexSizeThreshold)
      .Define("--swap-dex-count-threshold=_")
          .WithType<unsigned int>()
          .WithHelp("specifies the minimum number of dex file to allow the use of swap.")
          .IntoKey(M::SwapDexCountThreshold);
  // clang-format on
}

static void AddCompilerMappings(Builder& builder) {
  // clang-format off
  builder.
      Define("--run-passes=_")
          .WithType<std::string>()
          .IntoKey(M::Passes)
      .Define("--profile-file=_")
          .WithType<std::vector<std::string>>().AppendValues()
          .WithHelp("Specify profiler output file to use for compilation using a filename.\n"
                    "When multiple profiles are used, the order matters: If multiple profiles \n"
                    "contain classes and methods of the same dex file with different checksums, \n"
                    "only the classes and methods from the first profile will be used for that \n"
                    "particular dex file.")
          .IntoKey(M::Profile)
      .Define("--profile-file-fd=_")
          .WithType<std::vector<int>>().AppendValues()
          .WithHelp("Specify profiler output file to use for compilation using a file-descriptor.")
          .IntoKey(M::ProfileFd)
      .Define("--no-inline-from=_")
          .WithType<std::string>()
          .IntoKey(M::NoInlineFrom)
      .Define("--preloaded-classes=_")
          .WithType<std::vector<std::string>>().AppendValues()
          .WithHelp("Specify files containing list of classes preloaded in the zygote.")
          .IntoKey(M::PreloadedClasses)
      .Define("--preloaded-classes-fds=_")
          .WithType<std::vector<int>>().AppendValues()
          .WithHelp("Specify files containing list of classes preloaded in the zygote.")
          .IntoKey(M::PreloadedClassesFds);
  // clang-format on
}

static void AddTargetMappings(Builder& builder) {
  // clang-format off
  builder.
      Define("--instruction-set=_")
          .WithType<InstructionSet>()
          .WithHelp("Compile for a particular instruction set.")
          .IntoKey(M::TargetInstructionSet)
      .Define("--instruction-set-variant=_")
          .WithType<std::string>()
          .WithHelp("Specify instruction set features using variant name.\n"
                    "Eg: --instruction-set-variant=silvermont")
          .WithMetavar("{Variant Name}")
          .IntoKey(M::TargetInstructionSetVariant)
      .Define("--instruction-set-features=_")
          .WithType<std::string>()
          .WithHelp("Specify instruction set features.\n"
                    "On target the value 'runtime' can be used to detect features at run time.\n"
                    "If target does not support run-time detection the value 'runtime'\n"
                    "has the same effect as the value 'default'.\n"
                    "Note: the value 'runtime' has no effect if it is used on host.\n"
                    "Example: --instruction-set-features=div\n"
                    "Default: default")
          .IntoKey(M::TargetInstructionSetFeatures);
  // clang-format on
}

Parser CreateDex2oatArgumentParser() {
  std::unique_ptr<Builder> parser_builder = std::make_unique<Builder>();

  AddInputMappings(*parser_builder);
  AddGeneratedArtifactMappings(*parser_builder);
  AddImageMappings(*parser_builder);
  AddSwapMappings(*parser_builder);
  AddCompilerMappings(*parser_builder);
  AddTargetMappings(*parser_builder);

  // clang-format off
  parser_builder->
      Define({"--watch-dog", "--no-watch-dog"})
          .WithHelp("Enable or disable the watchdog timer.")
          .WithValues({true, false})
          .IntoKey(M::Watchdog)
      .Define("--watchdog-timeout=_")
          .WithType<int>()
          .WithHelp("Set the watchdog timeout value in milliseconds.")
          .IntoKey(M::WatchdogTimeout)
      .Define("-j_")
          .WithType<unsigned int>()
          .WithHelp("specifies the number of threads used for compilation. Default is the number\n"
                    "of detected hardware threads available on the host system.")
          .IntoKey(M::Threads)
      .Define("--cpu-set=_")
          .WithType<ParseIntList<','>>()
          .WithHelp("sets the cpu affinitiy to the given <set>. The <set> is a comma separated\n"
                    "list of cpus. Eg: --cpu-set=0,1,2,3")
          .WithMetavar("<set>")
          .IntoKey(M::CpuSet)
      .Define("--android-root=_")
          .WithType<std::string>()
          .WithHelp("Used to locate libraries for portable linking.\n"
                    "Eg: --android-root=out/host/linux-x86\n"
                    "Default: $ANDROID_ROOT")
          .IntoKey(M::AndroidRoot)
      .Define("--compiler-backend=_")
          .WithType<Compiler::Kind>()
          .WithValueMap({{"Quick", Compiler::Kind::kQuick},
                         {"Optimizing", Compiler::Kind::kOptimizing}})
          .WithHelp("Select a compiler backend set. Default: optimizing")
          .IntoKey(M::Backend)
      .Define("--host")
          .WithHelp("Run in host mode")
          .IntoKey(M::Host)
      .Define("--avoid-storing-invocation")
          .WithHelp("Avoid storing the invocation args in the key-value store. Used to test\n"
                    "determinism with different args.")
          .IntoKey(M::AvoidStoringInvocation)
      .Define("--very-large-app-threshold=_")
          .WithType<unsigned int>()
          .WithHelp("Specifies the minimum total dex file size in bytes to consider the input\n"
                    "\"very large\" and reduce compilation done.")
          .IntoKey(M::VeryLargeAppThreshold)
      .Define("--force-determinism")
          .WithHelp("Force the compiler to emit a deterministic output")
          .IntoKey(M::ForceDeterminism)
      .Define("--check-linkage-conditions")
          .IntoKey(M::CheckLinkageConditions)
      .Define("--crash-on-linkage-violation")
          .IntoKey(M::CrashOnLinkageViolation)
      .Define("--copy-dex-files=_")
          .WithType<linker::CopyOption>()
          .WithValueMap({{"true", linker::CopyOption::kOnlyIfCompressed},
                         {"false", linker::CopyOption::kNever},
                         {"always", linker::CopyOption::kAlways}})
          .WithHelp("enable|disable copying the dex files into the output vdex.")
          .IntoKey(M::CopyDexFiles)
      .Define("--force-allow-oj-inlines")
          .WithHelp("Disables automatic no-inline for core-oj on host. Has no effect on target."
                    " FOR TESTING USE ONLY! DO NOT DISTRIBUTE BINARIES BUILT WITH THIS OPTION!")
          .IntoKey(M::ForceAllowOjInlines)
      .Define("--write-invocation-to=_")
          .WithHelp("Write the invocation commandline to the given file for later use. Used to\n"
                    "test determinism with different args.")
          .WithType<std::string>()
          .IntoKey(M::InvocationFile)
      .Define("--classpath-dir=_")
          .WithType<std::string>()
          .WithHelp("Directory used to resolve relative class paths.")
          .IntoKey(M::ClasspathDir)
      .Define("--class-loader-context=_")
          .WithType<std::string>()
          .WithHelp("a string specifying the intended runtime loading context for the compiled\n"
                    "dex files.")
          .IntoKey(M::ClassLoaderContext)
      .Define("--class-loader-context-fds=_")
          .WithType<std::string>()
          .WithHelp("a colon-separated list of file descriptors for dex files in\n"
                    "--class-loader-context. Their order must be the same as dex files in a\n"
                    "flattened class loader context")
          .IntoKey(M::ClassLoaderContextFds)
      .Define("--stored-class-loader-context=_")
          .WithType<std::string>()
          .WithHelp("a string specifying the intended runtime loading context that is stored\n"
                    "in the oat file. Overrides --class-loader-context. Note that this ignores\n"
                    "the classpath_dir arg.\n"
                    "\n"
                    "It describes how the class loader chain should be built in order to ensure\n"
                    "classes are resolved during dex2aot as they would be resolved at runtime.\n"
                    "This spec will be encoded in the oat file. If at runtime the dex file is\n"
                    "loaded in a different context, the oat file will be rejected.\n"
                    "\n"
                    "The chain is interpreted in the natural 'parent order', meaning that class\n"
                    "loader 'i+1' will be the parent of class loader 'i'.\n"
                    "The compilation sources will be appended to the classpath of the first class\n"
                    "loader.\n"
                    "\n"
                    "E.g. if the context is 'PCL[lib1.dex];DLC[lib2.dex]' and \n"
                    "--dex-file=src.dex then dex2oat will setup a PathClassLoader with classpath \n"
                    "'lib1.dex:src.dex' and set its parent to a DelegateLastClassLoader with \n"
                    "classpath 'lib2.dex'.\n"
                    "\n"
                    "Note that the compiler will be tolerant if the source dex files specified\n"
                    "with --dex-file are found in the classpath. The source dex files will be\n"
                    "removed from any class loader's classpath possibly resulting in empty\n"
                    "class loaders.\n"
                    "\n"
                    "Example: --class-loader-context=PCL[lib1.dex:lib2.dex];DLC[lib3.dex]")
          .IntoKey(M::StoredClassLoaderContext)
      .Define("--compact-dex-level=_")
          .WithType<CompactDexLevel>()
          .WithValueMap({{"none", CompactDexLevel::kCompactDexLevelNone},
                         {"fast", CompactDexLevel::kCompactDexLevelFast}})
          .WithHelp("None avoids generating compact dex, fast generates compact dex with low\n"
                    "compile time. If speed-profile is specified as the compiler filter and the\n"
                    "profile is not empty, the default compact dex level is always used.")
          .IntoKey(M::CompactDexLevel)
      .Define("--runtime-arg _")
          .WithType<std::vector<std::string>>().AppendValues()
          .WithMetavar("{dalvikvm-arg}")
          .WithHelp("used to specify various arguments for the runtime, such as initial heap\n"
                    "size, maximum heap size, and verbose output. Use a separate --runtime-arg\n"
                    "switch for each argument.\n"
                    "Example: --runtime-arg -Xms256m")
          .IntoKey(M::RuntimeOptions)
      .Define("--compilation-reason=_")
          .WithType<std::string>()
          .WithHelp("optional metadata specifying the reason for compiling the apk. If specified,\n"
                    "the string will be embedded verbatim in the key value store of the oat file.\n"
                    "Example: --compilation-reason=install")
          .IntoKey(M::CompilationReason)
      .Define("--compile-individually")
          .WithHelp("Compiles dex files individually, unloading classes in between compiling each"
                    " file.")
          .IntoKey(M::CompileIndividually)
      .Define("--public-sdk=_")
          .WithType<std::string>()
          .IntoKey(M::PublicSdk)
      .Define("--apex-versions=_")
          .WithType<std::string>()
          .WithHelp("Versions of apexes in the boot classpath, separated by '/'")
          .IntoKey(M::ApexVersions)
      .Define("--force-jit-zygote")
          .WithHelp("Optimizes the app to be executed in an environment that uses JIT Zygote.")
          .IntoKey(M::ForceJitZygote)
      .Define("--force-palette-compilation-hooks")
          .WithHelp("Force PaletteNotify{Start,End}Dex2oatCompilation calls.")
          .IntoKey(M::ForcePaletteCompilationHooks)
      .Ignore({"--comments=_"});
  // clang-format on

  AddCompilerOptionsArgumentParserOptions<Dex2oatArgumentMap>(*parser_builder);

  parser_builder->IgnoreUnrecognized(false);

  return parser_builder->Build();
}

std::unique_ptr<Dex2oatArgumentMap> Dex2oatArgumentMap::Parse(int argc,
                                                              const char** argv,
                                                              std::string* error_msg) {
  Parser parser = CreateDex2oatArgumentParser();
  CmdlineResult parse_result = parser.Parse(argv, argc);
  if (!parse_result.IsSuccess()) {
    *error_msg = parse_result.GetMessage();
    return nullptr;
  }

  return std::make_unique<Dex2oatArgumentMap>(parser.ReleaseArgumentsMap());
}

#pragma GCC diagnostic pop
}  // namespace art
