/*
 * Copyright 2019 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 "os/system_properties.h"

#include <cutils/properties.h>

#include <array>
#include <cctype>

#include "common/strings.h"
#include "os/log.h"

namespace bluetooth {
namespace os {

std::optional<std::string> GetSystemProperty(const std::string& property) {
  std::array<char, PROPERTY_VALUE_MAX> value_array{0};
  auto value_len = property_get(property.c_str(), value_array.data(), nullptr);
  if (value_len <= 0) {
    return std::nullopt;
  }
  return std::string(value_array.data(), value_len);
}

bool SetSystemProperty(const std::string& property, const std::string& value) {
  if (value.size() >= PROPERTY_VALUE_MAX) {
    LOG_ERROR("Property value's maximum size is %d, but %zu chars were given", PROPERTY_VALUE_MAX - 1, value.size());
    return false;
  }
  auto ret = property_set(property.c_str(), value.c_str());
  if (ret != 0) {
    LOG_ERROR("Set property %s failed with error code %d", property.c_str(), ret);
    return false;
  }
  return true;
}

bool IsRootCanalEnabled() {
  auto value = GetSystemProperty("ro.vendor.build.fingerprint");
  if (value.has_value()) {
    LOG_INFO("ro.vendor.build.fingerprint='%s', length=%zu", value->c_str(), value->length());
  } else {
    LOG_INFO("ro.vendor.build.fingerprint is not found");
  }
  // aosp_cf_x86_64_phone is just one platform that currently runs root canal
  // When other platforms appears, or there is a better signal, add them here
  if (value->find("generic/aosp_cf_x86_64_phone") == std::string::npos) {
    LOG_INFO("Not on generic/aosp_cf_x86_64_phone and hence not root canal");
    return false;
  }
  return true;
}

int GetAndroidVendorReleaseVersion() {
  auto value = GetSystemProperty("ro.vendor.build.version.release_or_codename");
  if (!value) {
    LOG_INFO("ro.vendor.build.version.release_or_codename does not exist");
    return 0;
  }
  LOG_INFO("ro.vendor.build.version.release_or_codename='%s', length=%zu", value->c_str(), value->length());
  auto int_value = common::Int64FromString(*value);
  if (int_value) {
    return static_cast<int>(*int_value);
  }
  LOG_INFO("value '%s' cannot be parsed to int", value->c_str());
  if (value->empty()) {
    LOG_INFO("value '%s' is empty", value->c_str());
    return 0;
  }
  if (value->length() > 1) {
    LOG_INFO("value '%s' length is %zu, which is > 1", value->c_str(), value->length());
  }
  char release_code = toupper(value->at(0));
  switch (release_code) {
    case 'S':
      return 11;
    case 'R':
      return 10;
    case 'P':
      return 9;
    case 'O':
      return 8;
    default:
      // Treble not enabled before Android O
      return 0;
  }
}

}  // namespace os
}  // namespace bluetooth