/*
 * Copyright (C) 2021 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.
 */

#ifndef ART_RUNTIME_APP_INFO_H_
#define ART_RUNTIME_APP_INFO_H_

#include <vector>

#include "base/macros.h"
#include "base/mutex.h"
#include <base/safe_map.h>

namespace art HIDDEN {

// Constants used by VMRuntime.java to interface with the runtime.
// We could get them from the well known class but it's simpler to
// redefine them here.

// VMRuntime.CODE_PATH_TYPE_PRIMARY_APK
static constexpr int32_t kVMRuntimePrimaryApk = 1 << 0;
// VMRuntime.CODE_PATH_TYPE_SPLIT_APK
static constexpr int32_t kVMRuntimeSplitApk = 1 << 1;
// VMRuntime.CODE_PATH_TYPE_SECONDARY_DEX
static constexpr int32_t kVMRuntimeSecondaryDex = 1 << 2;

// Encapsulates the information the runtime has about the application.
//
// The app's info comes from 2 channels:
//   1) during class loading, when we load oat files.
//   2) during app startup, when the framework calls VMRuntime#registerAppInfo.
// In general the class loading event happens before VMRuntime#registerAppInfo.
class AppInfo {
 public:
  enum class CodeType {
    kUnknown,
    kPrimaryApk,
    kSplitApk,
    kSecondaryDex,
  };

  // Converts VMRuntime.java constansts to a CodeType.
  static CodeType FromVMRuntimeConstants(uint32_t code_type);

  AppInfo();

  // Registers the application code paths, types, and associated profiles.
  void RegisterAppInfo(const std::string& package_name,
                       const std::vector<std::string>& code_paths,
                       const std::string& profile_output_filename,
                       const std::string& ref_profile_filename,
                       CodeType code_type);

  // Registers the optimization status for single code path.
  void RegisterOdexStatus(const std::string& code_path,
                          const std::string& compiler_filter,
                          const std::string& compilation_reason,
                          const std::string& odex_status);

  // Extracts the optimization status of the primary APK into the given arguments.
  // If there are multiple primary APKs registed via RegisterAppInfo, the method
  // will assign the status of the first APK, sorted by the location name.
  //
  // Assigns "unknown" if there is no primary APK or the optimization status was
  // not set via RegisterOdexStatus,
  void GetPrimaryApkOptimizationStatus(std::string* out_compiler_filter,
                                       std::string* out_compilation_reason);

  // Returns the reference profile path of the primary APK.
  // If there are multiple primary APKs registed via RegisterAppInfo, the method
  // will return the profile of the first APK, sorted by the location name.
  //
  // Returns an empty string if there is no primary APK.
  std::string GetPrimaryApkReferenceProfile();

  // Whether we've received a call to RegisterAppInfo.
  bool HasRegisteredAppInfo();

  // The registered code type for a given code path. Note that this will
  // be kUnknown until an explicit registration for that path has been made.
  CodeType GetRegisteredCodeType(const std::string& code_path);

 private:
  // Encapsulates optimization information about a particular code location.
  struct CodeLocationInfo {
    // The type of the code location (primary, split, secondary, unknown).
    CodeType code_type{CodeType::kUnknown};

    // The compiler filter of the oat file. Note that this contains
    // the output of OatFileAssistant#GetOptimizationStatus() which may
    // contain values outside the scope of the CompilerFilter enum.
    std::optional<std::string> compiler_filter;

    // The compiler reason of the oat file. Note that this contains
    // the output of OatFileAssistant#GetOptimizationStatus().
    std::optional<std::string> compilation_reason;

    // The odes status as produced by OatFileAssistant#GetOptimizationStatus().
    std::optional<std::string> odex_status;

    // The path to the primary profile if given.
    std::optional<std::string> cur_profile_path;

    // The path to the reference profile if given.
    std::optional<std::string> ref_profile_path;
  };

  // The name of the package if set.
  std::optional<std::string> package_name_ GUARDED_BY(update_mutex_);

  // The registered code locations.
  SafeMap<std::string, CodeLocationInfo> registered_code_locations_ GUARDED_BY(update_mutex_);

  // Lock to touch the state ot the AppInfo object.
  art::Mutex update_mutex_ BOTTOM_MUTEX_ACQUIRED_AFTER;

  friend std::ostream& operator<<(std::ostream& os, AppInfo& rhs);
};

std::ostream& operator<<(std::ostream& os, AppInfo& rhs);

}  // namespace art

#endif  // ART_RUNTIME_APP_INFO_H_
