/*
 * Copyright (C) 2018 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 "src/profiling/memory/system_property.h"

#include "perfetto/base/logging.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/system_properties.h>
#endif

namespace perfetto {
namespace profiling {

SystemProperties::Handle::Handle(Handle&& other) {
  system_properties_ = other.system_properties_;
  property_ = std::move(other.property_);
  all_ = other.all_;
  other.system_properties_ = nullptr;
}

SystemProperties::Handle& SystemProperties::Handle::operator=(Handle&& other) {
  // Construct this temporary because the RHS could be an lvalue cast to an
  // rvalue reference whose lifetime we do not know.
  Handle tmp(std::move(other));
  using std::swap;
  swap(*this, tmp);
  return *this;
}

SystemProperties::Handle::Handle(SystemProperties* system_properties)
    : system_properties_(system_properties), all_(true) {}

SystemProperties::Handle::Handle(SystemProperties* system_properties,
                                 std::string property)
    : system_properties_(system_properties), property_(std::move(property)) {}

SystemProperties::Handle::~Handle() {
  if (system_properties_) {
    if (all_)
      system_properties_->UnsetAll();
    else
      system_properties_->UnsetProperty(property_);
  }
}

SystemProperties::Handle::operator bool() {
  return system_properties_ != nullptr;
}

SystemProperties::Handle SystemProperties::SetProperty(std::string name) {
  auto it = properties_.find(name);
  if (it == properties_.end()) {
    if (!SetAndroidProperty("heapprofd.enable." + name, "1"))
      return Handle(nullptr);
    if (properties_.size() == 1 || alls_ == 0) {
      if (!SetAndroidProperty("heapprofd.enable", "1"))
        return Handle(nullptr);
    }
    properties_.emplace(name, 1);
  } else {
    it->second++;
  }
  return Handle(this, std::move(name));
}

SystemProperties::Handle SystemProperties::SetAll() {
  if (alls_ == 0) {
    if (!SetAndroidProperty("heapprofd.enable", "all"))
      return Handle(nullptr);
  }
  alls_++;
  return Handle(this);
}

// This is conditionally noreturn, so disable the warning.
#pragma GCC diagnostic push
#if PERFETTO_DCHECK_IS_ON()
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#endif

// static
void SystemProperties::ResetHeapprofdProperties() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  int r = __system_property_foreach(
      [](const prop_info* pi, void*) {
        __system_property_read_callback(
            pi,
            [](void*, const char* name, const char*, uint32_t) {
              constexpr char kDebugModePropName[] = "heapprofd.userdebug.mode";

              // Unset everything starting with "heapprofd.", except for the
              // property stating which mode to use on debug builds.
              const char* found = strstr(name, "heapprofd.");
              if (found == name && strncmp(name, kDebugModePropName,
                                           strlen(kDebugModePropName))) {
                int ret = __system_property_set(name, "");
                PERFETTO_DCHECK(ret == 0);
              }
            },
            nullptr);
      },
      nullptr);
  PERFETTO_DCHECK(r == 0);
#else
  PERFETTO_DFATAL("Cannot ResetHeapprofdProperties on out-of-tree builds.");
#endif
}

#pragma GCC diagnostic pop

SystemProperties::~SystemProperties() {
  PERFETTO_DCHECK(alls_ == 0 && properties_.empty());
}

bool SystemProperties::SetAndroidProperty(const std::string& name,
                                          const std::string& value) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  return __system_property_set(name.c_str(), value.c_str()) == 0;
#else
  // Allow this to be mocked out for tests on other platforms.
  base::ignore_result(name);
  base::ignore_result(value);
  PERFETTO_FATAL("Properties can only be set on Android.");
#endif
}

void SystemProperties::UnsetProperty(const std::string& name) {
  auto it = properties_.find(name);
  if (it == properties_.end()) {
    PERFETTO_DFATAL("Unsetting unknown property.");
    return;
  }
  if (--(it->second) == 0) {
    properties_.erase(it);
    SetAndroidProperty("heapprofd.enable." + name, "");
    if (properties_.empty() && alls_ == 0)
      SetAndroidProperty("heapprofd.enable", "");
  }
}

void SystemProperties::UnsetAll() {
  if (--alls_ == 0) {
    if (properties_.empty())
      SetAndroidProperty("heapprofd.enable", "");
    else
      SetAndroidProperty("heapprofd.enable", "1");
  }
}

void swap(SystemProperties::Handle& a, SystemProperties::Handle& b) {
  using std::swap;
  swap(a.system_properties_, b.system_properties_);
  swap(a.property_, b.property_);
  swap(a.all_, b.all_);
}

}  // namespace profiling
}  // namespace perfetto
