/*
 * Copyright (C) 2017 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#pragma once

#include <string.h>
#include <sys/system_properties.h>

// Cached system property lookup. For code that needs to read the same property multiple times,
// this class helps optimize those lookups.
class CachedProperty {
 public:
  // The lifetime of `property_name` must be greater than that of this CachedProperty.
  explicit CachedProperty(const char* property_name)
    : property_name_(property_name),
      prop_info_(nullptr),
      cached_area_serial_(0),
      cached_property_serial_(0),
      is_read_only_(strncmp(property_name, "ro.", 3) == 0),
      read_only_property_(nullptr) {
    cached_value_[0] = '\0';
  }

  // Returns true if the property has been updated (based on the serial rather than the value)
  // since the last call to Get.
  bool DidChange() {
    uint32_t initial_property_serial_ = cached_property_serial_;
    Get();
    return (cached_property_serial_ != initial_property_serial_);
  }

  // Returns the current value of the underlying system property as cheaply as possible.
  // The returned pointer is valid until the next call to Get. It is the caller's responsibility
  // to provide a lock for thread-safety.
  const char* Get() {
    // Do we have a `struct prop_info` yet?
    if (prop_info_ == nullptr) {
      // `__system_property_find` is expensive, so only retry if a property
      // has been created since last time we checked.
      uint32_t property_area_serial = __system_property_area_serial();
      if (property_area_serial != cached_area_serial_) {
        prop_info_ = __system_property_find(property_name_);
        cached_area_serial_ = property_area_serial;
      }
    }

    if (prop_info_ != nullptr) {
      // Only bother re-reading the property if it's actually changed since last time.
      uint32_t property_serial = __system_property_serial(prop_info_);
      if (property_serial != cached_property_serial_) {
        __system_property_read_callback(prop_info_, &CachedProperty::Callback, this);
      }
    }
    if (is_read_only_ && read_only_property_ != nullptr) {
      return read_only_property_;
    }
    return cached_value_;
  }

 private:
  const char* property_name_;
  const prop_info* prop_info_;
  uint32_t cached_area_serial_;
  uint32_t cached_property_serial_;
  char cached_value_[PROP_VALUE_MAX];
  bool is_read_only_;
  const char* read_only_property_;

  static void Callback(void* data, const char*, const char* value, uint32_t serial) {
    CachedProperty* instance = reinterpret_cast<CachedProperty*>(data);
    instance->cached_property_serial_ = serial;
    // Read only properties can be larger than PROP_VALUE_MAX, but also never change value or
    // location, thus we return the pointer from the shared memory directly.
    if (instance->is_read_only_) {
      instance->read_only_property_ = value;
    } else {
      strlcpy(instance->cached_value_, value, PROP_VALUE_MAX);
    }
  }
};
