// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_ANDROID_BUILD_INFO_H_
#define BASE_ANDROID_BUILD_INFO_H_

#include <jni.h>

#include <string>
#include <vector>

#include "base/base_export.h"
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "starboard/types.h"

namespace base {
namespace android {

// This enumeration maps to the values returned by BuildInfo::sdk_int(),
// indicating the Android release associated with a given SDK version.
enum SdkVersion {
  SDK_VERSION_JELLY_BEAN = 16,
  SDK_VERSION_JELLY_BEAN_MR1 = 17,
  SDK_VERSION_JELLY_BEAN_MR2 = 18,
  SDK_VERSION_KITKAT = 19,
  SDK_VERSION_KITKAT_WEAR = 20,
  SDK_VERSION_LOLLIPOP = 21,
  SDK_VERSION_LOLLIPOP_MR1 = 22,
  SDK_VERSION_MARSHMALLOW = 23,
  SDK_VERSION_NOUGAT = 24,
  SDK_VERSION_NOUGAT_MR1 = 25,
  SDK_VERSION_OREO = 26,
};

// BuildInfo is a singleton class that stores android build and device
// information. It will be called from Android specific code and gets used
// primarily in crash reporting.
class BASE_EXPORT BuildInfo {
 public:

  ~BuildInfo() {}

  // Static factory method for getting the singleton BuildInfo instance.
  // Note that ownership is not conferred on the caller and the BuildInfo in
  // question isn't actually freed until shutdown. This is ok because there
  // should only be one instance of BuildInfo ever created.
  static BuildInfo* GetInstance();

  // Const char* is used instead of std::strings because these values must be
  // available even if the process is in a crash state. Sadly
  // std::string.c_str() doesn't guarantee that memory won't be allocated when
  // it is called.
  const char* device() const {
    return device_;
  }

  const char* manufacturer() const {
    return manufacturer_;
  }

  const char* model() const {
    return model_;
  }

  const char* brand() const {
    return brand_;
  }

  const char* android_build_id() const {
    return android_build_id_;
  }

  const char* android_build_fp() const {
    return android_build_fp_;
  }

  const char* gms_version_code() const {
    return gms_version_code_;
  }

  const char* host_package_name() const { return host_package_name_; }

  const char* host_version_code() const { return host_version_code_; }

  const char* host_package_label() const { return host_package_label_; }

  const char* package_version_code() const {
    return package_version_code_;
  }

  const char* package_version_name() const {
    return package_version_name_;
  }

  const char* package_name() const {
    return package_name_;
  }

  // Will be empty string if no app id is assigned.
  const char* firebase_app_id() const { return firebase_app_id_; }

  const char* custom_themes() const { return custom_themes_; }

  const char* resources_version() const { return resources_version_; }

  const char* build_type() const {
    return build_type_;
  }

  const char* board() const { return board_; }

  const char* installer_package_name() const { return installer_package_name_; }

  const char* abi_name() const { return abi_name_; }

  std::string extracted_file_suffix() const { return extracted_file_suffix_; }

  int sdk_int() const {
    return sdk_int_;
  }

  bool is_at_least_p() const { return is_at_least_p_; }

 private:
  friend struct BuildInfoSingletonTraits;

  explicit BuildInfo(const std::vector<std::string>& params);

  // Const char* is used instead of std::strings because these values must be
  // available even if the process is in a crash state. Sadly
  // std::string.c_str() doesn't guarantee that memory won't be allocated when
  // it is called.
  const char* const brand_;
  const char* const device_;
  const char* const android_build_id_;
  const char* const manufacturer_;
  const char* const model_;
  const int sdk_int_;
  const char* const build_type_;
  const char* const board_;
  const char* const host_package_name_;
  const char* const host_version_code_;
  const char* const host_package_label_;
  const char* const package_name_;
  const char* const package_version_code_;
  const char* const package_version_name_;
  const char* const android_build_fp_;
  const char* const gms_version_code_;
  const char* const installer_package_name_;
  const char* const abi_name_;
  const char* const firebase_app_id_;
  const char* const custom_themes_;
  const char* const resources_version_;
  // Not needed by breakpad.
  const std::string extracted_file_suffix_;
  const int is_at_least_p_;

  DISALLOW_COPY_AND_ASSIGN(BuildInfo);
};

}  // namespace android
}  // namespace base

#endif  // BASE_ANDROID_BUILD_INFO_H_
