/*
 * Copyright (C) 2020 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 <sys/stat.h>

#include <string>
#include <string_view>

#include "android-base/properties.h"
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "arch/instruction_set.h"
#include "base/file_utils.h"
#include "base/globals.h"
#include "odr_common.h"
#include "odr_compilation_log.h"
#include "odr_config.h"
#include "odr_metrics.h"
#include "odrefresh.h"
#include "odrefresh/odrefresh.h"

namespace {

using ::art::odrefresh::CompilationOptions;
using ::art::odrefresh::ExitCode;
using ::art::odrefresh::OdrCompilationLog;
using ::art::odrefresh::OdrConfig;
using ::art::odrefresh::OdrMetrics;
using ::art::odrefresh::OnDeviceRefresh;
using ::art::odrefresh::QuotePath;
using ::art::odrefresh::ShouldDisablePartialCompilation;
using ::art::odrefresh::ShouldDisableRefresh;
using ::art::odrefresh::ZygoteKind;

void UsageMsgV(const char* fmt, va_list ap) {
  std::string error;
  android::base::StringAppendV(&error, fmt, ap);
  if (isatty(fileno(stderr))) {
    std::cerr << error << std::endl;
  } else {
    LOG(ERROR) << error;
  }
}

void UsageMsg(const char* fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  UsageMsgV(fmt, ap);
  va_end(ap);
}

NO_RETURN void ArgumentError(const char* fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  UsageMsgV(fmt, ap);
  va_end(ap);
  UsageMsg("Try '--help' for more information.");
  exit(EX_USAGE);
}

bool ParseZygoteKind(const char* input, ZygoteKind* zygote_kind) {
  std::string_view z(input);
  if (z == "zygote32") {
    *zygote_kind = ZygoteKind::kZygote32;
    return true;
  } else if (z == "zygote32_64") {
    *zygote_kind = ZygoteKind::kZygote32_64;
    return true;
  } else if (z == "zygote64_32") {
    *zygote_kind = ZygoteKind::kZygote64_32;
    return true;
  } else if (z == "zygote64") {
    *zygote_kind = ZygoteKind::kZygote64;
    return true;
  }
  return false;
}

std::string GetEnvironmentVariableOrDie(const char* name) {
  const char* value = getenv(name);
  LOG_ALWAYS_FATAL_IF(value == nullptr, "%s is not defined.", name);
  return value;
}

std::string GetEnvironmentVariableOrDefault(const char* name, std::string default_value) {
  const char* value = getenv(name);
  if (value == nullptr) {
    return default_value;
  }
  return value;
}

bool ArgumentMatches(std::string_view argument, std::string_view prefix, std::string* value) {
  if (android::base::StartsWith(argument, prefix)) {
    *value = std::string(argument.substr(prefix.size()));
    return true;
  }
  return false;
}

bool ArgumentEquals(std::string_view argument, std::string_view expected) {
  return argument == expected;
}

int InitializeConfig(int argc, char** argv, OdrConfig* config) {
  config->SetApexInfoListFile("/apex/apex-info-list.xml");
  config->SetArtBinDir(art::GetArtBinDir());
  config->SetBootClasspath(GetEnvironmentVariableOrDie("BOOTCLASSPATH"));
  config->SetDex2oatBootclasspath(GetEnvironmentVariableOrDie("DEX2OATBOOTCLASSPATH"));
  config->SetSystemServerClasspath(GetEnvironmentVariableOrDie("SYSTEMSERVERCLASSPATH"));
  config->SetStandaloneSystemServerJars(
      GetEnvironmentVariableOrDefault("STANDALONE_SYSTEMSERVER_JARS", /*default_value=*/""));
  config->SetIsa(art::kRuntimeISA);

  std::string zygote;
  int n = 1;
  for (; n < argc - 1; ++n) {
    const char* arg = argv[n];
    std::string value;
    if (ArgumentEquals(arg, "--compilation-os-mode")) {
      config->SetCompilationOsMode(true);
    } else if (ArgumentMatches(arg, "--dalvik-cache=", &value)) {
      art::OverrideDalvikCacheSubDirectory(value);
      config->SetArtifactDirectory(GetApexDataDalvikCacheDirectory(art::InstructionSet::kNone));
    } else if (ArgumentMatches(arg, "--zygote-arch=", &value)) {
      zygote = value;
    } else if (ArgumentMatches(arg, "--system-server-compiler-filter=", &value)) {
      config->SetSystemServerCompilerFilter(value);
    } else if (ArgumentMatches(arg, "--staging-dir=", &value)) {
      config->SetStagingDir(value);
    } else if (ArgumentEquals(arg, "--dry-run")) {
      config->SetDryRun();
    } else if (ArgumentEquals(arg, "--partial-compilation")) {
      config->SetPartialCompilation(true);
    } else if (ArgumentEquals(arg, "--no-refresh")) {
      config->SetRefresh(false);
    } else if (ArgumentEquals(arg, "--minimal")) {
      config->SetMinimal(true);
    } else {
      ArgumentError("Unrecognized argument: '%s'", arg);
    }
  }

  if (zygote.empty()) {
    // Use ro.zygote by default, if not overridden by --zygote-arch flag.
    zygote = android::base::GetProperty("ro.zygote", {});
  }
  ZygoteKind zygote_kind;
  if (!ParseZygoteKind(zygote.c_str(), &zygote_kind)) {
    LOG(FATAL) << "Unknown zygote: " << QuotePath(zygote);
  }
  config->SetZygoteKind(zygote_kind);

  if (config->GetSystemServerCompilerFilter().empty()) {
    std::string filter =
        android::base::GetProperty("dalvik.vm.systemservercompilerfilter", "speed");
    config->SetSystemServerCompilerFilter(filter);
  }

  if (!config->HasPartialCompilation() &&
      ShouldDisablePartialCompilation(
          android::base::GetProperty("ro.build.version.security_patch", /*default_value=*/""))) {
    config->SetPartialCompilation(false);
  }

  if (ShouldDisableRefresh(
          android::base::GetProperty("ro.build.version.sdk", /*default_value=*/""))) {
    config->SetRefresh(false);
  }

  return n;
}

NO_RETURN void UsageHelp(const char* argv0) {
  std::string name(android::base::Basename(argv0));
  UsageMsg("Usage: %s [OPTION...] ACTION", name.c_str());
  UsageMsg("On-device refresh tool for boot classpath and system server");
  UsageMsg("following an update of the ART APEX.");
  UsageMsg("");
  UsageMsg("Valid ACTION choices are:");
  UsageMsg("");
  UsageMsg("--check          Check compilation artifacts are up-to-date based on metadata.");
  UsageMsg("--compile        Compile boot classpath and system_server jars when necessary.");
  UsageMsg("--force-compile  Unconditionally compile the bootclass path and system_server jars.");
  UsageMsg("--help           Display this help information.");
  UsageMsg("");
  UsageMsg("Available OPTIONs are:");
  UsageMsg("");
  UsageMsg("--dry-run");
  UsageMsg("--partial-compilation            Only generate artifacts that are out-of-date or");
  UsageMsg("                                 missing.");
  UsageMsg("--no-refresh                     Do not refresh existing artifacts.");
  UsageMsg("--compilation-os-mode            Indicate that odrefresh is running in Compilation");
  UsageMsg("                                 OS.");
  UsageMsg("--dalvik-cache=<DIR>             Write artifacts to .../<DIR> rather than");
  UsageMsg("                                 .../dalvik-cache");
  UsageMsg("--staging-dir=<DIR>              Write temporary artifacts to <DIR> rather than");
  UsageMsg("                                 .../staging");
  UsageMsg("--zygote-arch=<STRING>           Zygote kind that overrides ro.zygote");
  UsageMsg("--system-server-compiler-filter=<STRING>");
  UsageMsg("                                 Compiler filter that overrides");
  UsageMsg("                                 dalvik.vm.systemservercompilerfilter");
  UsageMsg("--minimal                        Generate a minimal boot image only.");

  exit(EX_USAGE);
}

}  // namespace

int main(int argc, char** argv) {
  // odrefresh is launched by `init` which sets the umask of forked processed to
  // 077 (S_IRWXG | S_IRWXO). This blocks the ability to make files and directories readable
  // by others and prevents system_server from loading generated artifacts.
  umask(S_IWGRP | S_IWOTH);

  // Explicitly initialize logging (b/201042799).
  android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));

  OdrConfig config(argv[0]);
  int n = InitializeConfig(argc, argv, &config);
  argv += n;
  argc -= n;
  if (argc != 1) {
    ArgumentError("Expected 1 argument, but have %d.", argc);
  }

  OdrMetrics metrics(config.GetArtifactDirectory());
  OnDeviceRefresh odr(config);

  std::string_view action(argv[0]);
  CompilationOptions compilation_options;
  if (action == "--check") {
    // Fast determination of whether artifacts are up to date.
    return odr.CheckArtifactsAreUpToDate(metrics, &compilation_options);
  } else if (action == "--compile") {
    const ExitCode exit_code = odr.CheckArtifactsAreUpToDate(metrics, &compilation_options);
    if (exit_code != ExitCode::kCompilationRequired) {
      return exit_code;
    }
    OdrCompilationLog compilation_log;
    if (!compilation_log.ShouldAttemptCompile(metrics.GetTrigger())) {
      LOG(INFO) << "Compilation skipped because it was attempted recently";
      return ExitCode::kOkay;
    }
    ExitCode compile_result = odr.Compile(metrics, compilation_options);
    compilation_log.Log(metrics.GetArtApexVersion(),
                        metrics.GetArtApexLastUpdateMillis(),
                        metrics.GetTrigger(),
                        compile_result);
    return compile_result;
  } else if (action == "--force-compile") {
    // Clean-up existing files.
    if (!odr.RemoveArtifactsDirectory()) {
      metrics.SetStatus(OdrMetrics::Status::kIoError);
      return ExitCode::kCleanupFailed;
    }
    return odr.Compile(metrics,
                       CompilationOptions{
                           .compile_boot_classpath_for_isas = config.GetBootClasspathIsas(),
                           .system_server_jars_to_compile = odr.AllSystemServerJars(),
                       });
  } else if (action == "--help") {
    UsageHelp(argv[0]);
  } else {
    ArgumentError("Unknown argument: ", action);
  }
}
