// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "featured/feature_library.h"

#include <utility>

#include <base/bind.h>
#include <base/logging.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/message.h>

#include <brillo/dbus/dbus_connection.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <brillo/dbus/dbus_proxy_util.h>
#include <brillo/errors/error.h>

namespace feature {

PlatformFeatures::PlatformFeatures(scoped_refptr<dbus::Bus> bus,
                                   dbus::ObjectProxy* proxy)
    : bus_(bus), proxy_(proxy) {}

std::unique_ptr<PlatformFeatures> PlatformFeatures::New(
    scoped_refptr<dbus::Bus> bus) {
  auto* proxy = bus->GetObjectProxy(
      chromeos::kChromeFeaturesServiceName,
      dbus::ObjectPath(chromeos::kChromeFeaturesServicePath));
  if (!proxy) {
    LOG(ERROR) << "Failed to create object proxy for "
               << chromeos::kChromeFeaturesServiceName;
    return nullptr;
  }

  return std::unique_ptr<PlatformFeatures>(new PlatformFeatures(bus, proxy));
}

void PlatformFeatures::IsEnabled(const VariationsFeature& feature,
                                 IsEnabledCallback callback) {
  DCHECK(CheckFeatureIdentity(feature)) << feature.name;

  proxy_->WaitForServiceToBeAvailable(base::BindOnce(
      &PlatformFeatures::OnWaitForService, weak_ptr_factory_.GetWeakPtr(),
      feature, std::move(callback)));
}

bool PlatformFeatures::IsEnabledBlocking(const VariationsFeature& feature) {
  DCHECK(CheckFeatureIdentity(feature)) << feature.name;

  dbus::MethodCall call(chromeos::kChromeFeaturesServiceInterface,
                        chromeos::kChromeFeaturesServiceIsFeatureEnabledMethod);
  dbus::MessageWriter writer(&call);
  writer.AppendString(feature.name);
  std::unique_ptr<dbus::Response> response = brillo::dbus_utils::CallDBusMethod(
      bus_, proxy_, &call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
  if (!response) {
    return feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
  }

  dbus::MessageReader reader(response.get());
  bool feature_enabled = false;
  if (!reader.PopBool(&feature_enabled)) {
    LOG(ERROR) << "failed to read bool from dbus result; using default value";
    return feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
  }

  return feature_enabled;
}

void PlatformFeatures::OnWaitForService(const VariationsFeature& feature,
                                        IsEnabledCallback callback,
                                        bool available) {
  if (!available) {
    std::move(callback).Run(feature.default_state ==
                            FEATURE_ENABLED_BY_DEFAULT);
    LOG(ERROR) << "failed to connect to dbus service; using default value";
    return;
  }
  dbus::MethodCall call(chromeos::kChromeFeaturesServiceInterface,
                        chromeos::kChromeFeaturesServiceIsFeatureEnabledMethod);
  dbus::MessageWriter writer(&call);
  writer.AppendString(feature.name);
  proxy_->CallMethod(&call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
                     base::BindOnce(&PlatformFeatures::HandleIsEnabledResponse,
                                    weak_ptr_factory_.GetWeakPtr(), feature,
                                    std::move(callback)));
}

void PlatformFeatures::HandleIsEnabledResponse(const VariationsFeature& feature,
                                               IsEnabledCallback callback,
                                               dbus::Response* response) {
  if (!response) {
    LOG(ERROR) << "dbus call failed; using default value";
    std::move(callback).Run(feature.default_state ==
                            FEATURE_ENABLED_BY_DEFAULT);
    return;
  }

  dbus::MessageReader reader(response);
  bool feature_enabled = false;
  if (!reader.PopBool(&feature_enabled)) {
    LOG(ERROR) << "failed to read bool from dbus result; using default value";
    std::move(callback).Run(feature.default_state ==
                            FEATURE_ENABLED_BY_DEFAULT);
    return;
  }

  std::move(callback).Run(feature_enabled);
}

bool PlatformFeatures::CheckFeatureIdentity(const VariationsFeature& feature) {
  base::AutoLock auto_lock(lock_);

  auto it = feature_identity_tracker_.find(feature.name);
  if (it == feature_identity_tracker_.end()) {
    // If it's not tracked yet, register it.
    feature_identity_tracker_[feature.name] = &feature;
    return true;
  }
  // Compare address of |feature| to the existing tracked entry.
  return it->second == &feature;
}

void PlatformFeatures::ShutdownBus() {
  bus_->ShutdownAndBlock();
}

// FakePlatformFeatures
void FakePlatformFeatures::IsEnabled(const VariationsFeature& feature,
                                     IsEnabledCallback callback) {
  base::AutoLock auto_lock(enabled_lock_);
  bus_->AssertOnOriginThread();
  auto it = enabled_.find(feature.name);
  bool enabled = feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
  if (it != enabled_.end()) {
    enabled = it->second;
  }
  bus_->GetOriginTaskRunner()->PostTask(
      FROM_HERE, base::BindOnce(std::move(callback), enabled));
}

bool FakePlatformFeatures::IsEnabledBlocking(const VariationsFeature& feature) {
  base::AutoLock auto_lock(enabled_lock_);
  auto it = enabled_.find(feature.name);
  if (it != enabled_.end()) {
    return it->second;
  }
  return feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
}

void FakePlatformFeatures::SetEnabled(const std::string& feature,
                                      bool enabled) {
  base::AutoLock auto_lock(enabled_lock_);
  enabled_[feature] = enabled;
}

void FakePlatformFeatures::ClearEnabled(const std::string& feature) {
  base::AutoLock auto_lock(enabled_lock_);
  auto it = enabled_.find(feature);
  if (it != enabled_.end()) {
    enabled_.erase(it);
  }
}

void FakePlatformFeatures::ShutdownBus() {
  bus_->ShutdownAndBlock();
}

}  // namespace feature
