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

// clang-format off
#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
#include <Weave/DeviceLayer/internal/GenericConfigurationManagerImpl.ipp>

#include "src/connectivity/weave/adaptation/configuration_manager_delegate_impl.h"
#include "src/connectivity/weave/adaptation/group_key_store_impl.h"
// clang-format on

#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fit/defer.h>
#include <lib/syslog/cpp/macros.h>
#include <net/ethernet.h>
#include <sys/stat.h>
#include <unistd.h>
#include <zircon/status.h>

#include "src/lib/files/file.h"
#include "src/lib/fsl/vmo/file.h"
#include "src/lib/fsl/vmo/strings.h"

#include <filesystem>

namespace nl {
namespace Weave {
namespace DeviceLayer {

namespace {

using ::nl::Weave::DeviceLayer::Internal::EnvironmentConfig;
using ::nl::Weave::DeviceLayer::Internal::GenericConfigurationManagerImpl;
using ::nl::Weave::DeviceLayer::Internal::WeaveConfigManager;
using ::nl::Weave::Profiles::Security::AppKeys::GroupKeyStoreBase;

// Store path and keys for static device information.
constexpr char kDeviceInfoStorePath[] = "/config/data/device_info.json";
constexpr char kDeviceInfoConfigKey_BleDeviceNamePrefix[] = "ble-device-name-prefix";
constexpr char kDeviceInfoConfigKey_DeviceId[] = "device-id";
constexpr char kDeviceInfoConfigKey_DeviceIdPath[] = "device-id-path";
constexpr char kDeviceInfoConfigKey_EnableWoBLE[] = "enable-woble";
constexpr char kDeviceInfoConfigKey_EnableWoBLEAdvertisement[] = "enable-woble-advertisement";
constexpr char kDeviceInfoConfigKey_FirmwareRevision[] = "firmware-revision";
constexpr char kDeviceInfoConfigKey_MfrDeviceCertPath[] = "mfr-device-cert-path";
constexpr char kDeviceInfoConfigKey_MfrDeviceCertAllowLocal[] = "mfr-device-cert-allow-local";
constexpr char kDeviceInfoConfigKey_PrivateKeyPath[] = "mfr-private-key-path";
constexpr char kDeviceInfoConfigKey_ProductId[] = "product-id";
constexpr char kDeviceInfoConfigKey_SerialNumber[] = "serial-number";
constexpr char kDeviceInfoConfigKey_VendorId[] = "vendor-id";

// Maximum number of chars in hex for a uint64_t.
constexpr int kWeaveDeviceIdMaxLength = 16;

// Maximum size of Weave certificate.
constexpr int kWeaveCertificateMaxLength = UINT16_MAX;

// Storage path for data files.
const std::string kDataPath = "/data/";

}  // unnamed namespace

ConfigurationManagerDelegateImpl::ConfigurationManagerDelegateImpl()
    : device_info_(WeaveConfigManager::CreateReadOnlyInstance(kDeviceInfoStorePath)) {}

WEAVE_ERROR ConfigurationManagerDelegateImpl::Init() {
  WEAVE_ERROR err = WEAVE_NO_ERROR;
  auto context = PlatformMgrImpl().GetComponentContextForProcess();

  FX_CHECK(context->svc()->Connect(hwinfo_device_.NewRequest()) == ZX_OK)
      << "Failed to connect to hwinfo device service.";
  FX_CHECK(context->svc()->Connect(weave_factory_data_manager_.NewRequest()) == ZX_OK)
      << "Failed to connect to weave factory data manager service.";
  FX_CHECK(context->svc()->Connect(factory_store_provider_.NewRequest()) == ZX_OK)
      << "Failed to connect to factory store";

  err = EnvironmentConfig::Init();
  if (err != WEAVE_NO_ERROR) {
    return err;
  }

  err = static_cast<GenericConfigurationManagerImpl<ConfigurationManagerImpl>*>(impl_)->_Init();
  if (err != WEAVE_NO_ERROR) {
    return err;
  }

  err = GetAndStoreHWInfo();
  if (err != WEAVE_NO_ERROR && err != WEAVE_DEVICE_ERROR_CONFIG_NOT_FOUND) {
    return err;
  }

  err = GetAndStorePairingCode();
  if (err != WEAVE_NO_ERROR && err != WEAVE_DEVICE_ERROR_CONFIG_NOT_FOUND) {
    return err;
  }

  return WEAVE_NO_ERROR;
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::GetDeviceId(uint64_t& device_id) {
  WEAVE_ERROR err =
      EnvironmentConfig::ReadConfigValue(EnvironmentConfig::kConfigKey_MfrDeviceId, device_id);
  if (err == WEAVE_NO_ERROR) {
    return WEAVE_NO_ERROR;
  }

  err = device_info_->ReadConfigValue(kDeviceInfoConfigKey_DeviceId, &device_id);
  if (err != WEAVE_DEVICE_ERROR_CONFIG_NOT_FOUND) {
    return err;
  }

  char path[PATH_MAX] = {'\0'};
  size_t out_size;
  err = device_info_->ReadConfigValueStr(kDeviceInfoConfigKey_DeviceIdPath, path, sizeof(path),
                                         &out_size);
  if (err == WEAVE_NO_ERROR) {
    err = GetDeviceIdFromFactory(path, &device_id);
    FX_CHECK(err == WEAVE_NO_ERROR) << "Failed getting device id from factory at path: " << path;
    impl_->StoreManufacturerDeviceId(device_id);
    return err;
  }

  err = GetDeviceIdFromFactory(path, &device_id);
  if (err != WEAVE_NO_ERROR) {
    return err;
  }

  return impl_->StoreManufacturerDeviceId(device_id);
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::GetManufacturerDeviceCertificate(uint8_t* buf,
                                                                               size_t buf_size,
                                                                               size_t& out_len) {
  WEAVE_ERROR err = EnvironmentConfig::ReadConfigValueBin(
      EnvironmentConfig::kConfigKey_MfrDeviceCert, buf, buf_size, out_len);
  if (err == WEAVE_NO_ERROR) {
    return err;
  }

  err = GetAndStoreMfrDeviceCert();
  if (err != WEAVE_NO_ERROR) {
    return err;
  }

  return EnvironmentConfig::ReadConfigValueBin(EnvironmentConfig::kConfigKey_MfrDeviceCert, buf,
                                               buf_size, out_len);
}

bool ConfigurationManagerDelegateImpl::IsFullyProvisioned() {
  return ConnectivityMgr().IsWiFiStationProvisioned() &&
         // TODO(fxbug.dev/58252) Due to incomplete implementation of ThreadStackManager, this
         // predicate does not yet include the line `ConnectivityMgr().IsThreadProvisioned() &&`,
         // but should once complete.
         ConfigurationMgr().IsPairedToAccount() && ConfigurationMgr().IsMemberOfFabric();
}

bool ConfigurationManagerDelegateImpl::IsPairedToAccount() {
  // By default, just use the generic implementation in Weave Device Layer.
  return static_cast<GenericConfigurationManagerImpl<ConfigurationManagerImpl>*>(impl_)
      ->_IsPairedToAccount();
}

bool ConfigurationManagerDelegateImpl::IsMemberOfFabric() {
  // By default, just use the generic implementation in Weave Device Layer.
  return static_cast<GenericConfigurationManagerImpl<ConfigurationManagerImpl>*>(impl_)
      ->_IsMemberOfFabric();
}

GroupKeyStoreBase* ConfigurationManagerDelegateImpl::GetGroupKeyStore() {
  return &group_key_store_;
}

bool ConfigurationManagerDelegateImpl::CanFactoryReset() { return true; }

void ConfigurationManagerDelegateImpl::InitiateFactoryReset() {
  EnvironmentConfig::FactoryResetConfig();
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::ReadPersistedStorageValue(Key key, uint32_t& value) {
  WEAVE_ERROR err = EnvironmentConfig::ReadConfigValue(key, value);
  return (err == WEAVE_DEVICE_ERROR_CONFIG_NOT_FOUND)
             ? WEAVE_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND
             : err;
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::WritePersistedStorageValue(Key key, uint32_t value) {
  WEAVE_ERROR err = EnvironmentConfig::WriteConfigValue(key, value);
  return (err != WEAVE_NO_ERROR) ? WEAVE_ERROR_PERSISTED_STORAGE_FAIL : err;
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::GetVendorId(uint16_t& vendor_id) {
  return device_info_->ReadConfigValue(kDeviceInfoConfigKey_VendorId, &vendor_id);
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::GetProductId(uint16_t& product_id) {
  return device_info_->ReadConfigValue(kDeviceInfoConfigKey_ProductId, &product_id);
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::GetFirmwareRevision(char* buf, size_t buf_size,
                                                                  size_t& out_len) {
  return device_info_->ReadConfigValueStr(kDeviceInfoConfigKey_FirmwareRevision, buf, buf_size,
                                          &out_len);
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::GetBleDeviceNamePrefix(char* device_name_prefix,
                                                                     size_t device_name_prefix_size,
                                                                     size_t* out_len) {
  return device_info_->ReadConfigValueStr(kDeviceInfoConfigKey_BleDeviceNamePrefix,
                                          device_name_prefix, device_name_prefix_size, out_len);
}

bool ConfigurationManagerDelegateImpl::IsWoBLEEnabled() {
  bool is_enabled = false;
  device_info_->ReadConfigValue(kDeviceInfoConfigKey_EnableWoBLE, &is_enabled);
  return is_enabled;
}

bool ConfigurationManagerDelegateImpl::IsWoBLEAdvertisementEnabled() {
  bool is_enabled = IsWoBLEEnabled();
  if (is_enabled) {
    device_info_->ReadConfigValue(kDeviceInfoConfigKey_EnableWoBLEAdvertisement, &is_enabled);
  }
  return is_enabled;
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::GetDeviceDescriptorTLV(uint8_t* buf, size_t buf_size,
                                                                     size_t& encoded_len) {
  return static_cast<GenericConfigurationManagerImpl<ConfigurationManagerImpl>*>(impl_)
      ->_GetDeviceDescriptorTLV(buf, buf_size, encoded_len);
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::GetAndStoreHWInfo() {
  fuchsia::hwinfo::DeviceInfo device_info;
  WEAVE_ERROR err;
  char serial[ConfigurationManager::kMaxSerialNumberLength + 1];
  size_t serial_size = 0;
  if (ZX_OK == hwinfo_device_->GetInfo(&device_info) && device_info.has_serial_number()) {
    return impl_->StoreSerialNumber(device_info.serial_number().c_str(),
                                    device_info.serial_number().length());
  } else if ((err =
                  device_info_->ReadConfigValueStr(kDeviceInfoConfigKey_SerialNumber, serial,
                                                   ConfigurationManager::kMaxSerialNumberLength + 1,
                                                   &serial_size)) == WEAVE_NO_ERROR) {
    return impl_->StoreSerialNumber(serial, serial_size);
  }
  return WEAVE_DEVICE_ERROR_CONFIG_NOT_FOUND;
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::GetAndStorePairingCode() {
  fuchsia::weave::FactoryDataManager_GetPairingCode_Result pairing_code_result;
  fuchsia::weave::FactoryDataManager_GetPairingCode_Response pairing_code_response;
  std::string pairing_code;
  char read_value[ConfigurationManager::kMaxPairingCodeLength + 1];
  size_t read_value_size = 0;
  WEAVE_ERROR err;

  // If a pairing code is provided in config-data, it takes precedent over the
  // value provided by the factory data manager.
  err = device_info_->ReadConfigValueStr(EnvironmentConfig::kConfigKey_PairingCode, read_value,
                                         ConfigurationManager::kMaxPairingCodeLength + 1,
                                         &read_value_size);
  if (err == WEAVE_NO_ERROR) {
    return impl_->StorePairingCode(read_value, read_value_size);
  }

  // Otherwise, use the factory data manager as the source of truth.
  zx_status_t status = weave_factory_data_manager_->GetPairingCode(&pairing_code_result);
  if (ZX_OK != status || !pairing_code_result.is_response()) {
    return WEAVE_DEVICE_ERROR_CONFIG_NOT_FOUND;
  }

  pairing_code_response = pairing_code_result.response();
  if (pairing_code_response.pairing_code.size() > ConfigurationManager::kMaxPairingCodeLength) {
    return WEAVE_DEVICE_ERROR_CONFIG_NOT_FOUND;
  }

  return impl_->StorePairingCode((const char*)pairing_code_response.pairing_code.data(),
                                 pairing_code_response.pairing_code.size());
}

WEAVE_ERROR ConfigurationManagerDelegateImpl::GetAndStoreMfrDeviceCert() {
  char path[PATH_MAX] = {'\0'};
  char mfr_cert[kWeaveCertificateMaxLength];
  std::string cert;
  size_t out_size;
  zx_status_t status;
  WEAVE_ERROR err;
  bool allow_local = false;
  std::filesystem::path full_path(kDataPath);

  // Check if a test cert was provided and read the same.
  err = EnvironmentConfig::ReadConfigValue(EnvironmentConfig::kConfigKey_MfrDeviceCertAllowLocal,
                                           allow_local);
  if (err != WEAVE_NO_ERROR) {
    device_info_->ReadConfigValue(kDeviceInfoConfigKey_MfrDeviceCertAllowLocal, &allow_local);
  }
  if (allow_local) {
    err = device_info_->ReadConfigValueStr(kDeviceInfoConfigKey_MfrDeviceCertPath, path,
                                           sizeof(path), &out_size);
    if (err != WEAVE_NO_ERROR) {
      FX_LOGS(ERROR) << "Local manufacturer cert path not found";
      return err;
    }

    full_path.append(path);
    if (!files::ReadFileToString(full_path.string(), &cert)) {
      FX_LOGS(ERROR) << "failed reading " << path;
      return ZX_ERR_INTERNAL;
    }

    return impl_->StoreManufacturerDeviceCertificate(reinterpret_cast<uint8_t*>(cert.data()),
                                                     cert.size());
  }

  // Read file from factory.
  err = device_info_->ReadConfigValueStr(kDeviceInfoConfigKey_MfrDeviceCertPath, path, sizeof(path),
                                         &out_size);

  if (err != WEAVE_NO_ERROR) {
    FX_LOGS(ERROR) << "No manufacturer device certificate was found";
    return err;
  }

  status = ReadFactoryFile(path, mfr_cert, sizeof(mfr_cert), &out_size);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed getting manufacturer certificate from factory with status "
                   << zx_status_get_string(status) << " for path: " << path;
    return WEAVE_DEVICE_ERROR_CONFIG_NOT_FOUND;
  }

  return impl_->StoreManufacturerDeviceCertificate(reinterpret_cast<uint8_t*>(mfr_cert), out_size);
}

zx_status_t ConfigurationManagerDelegateImpl::GetPrivateKeyForSigning(std::vector<uint8_t>* signing_key) {
  char path[PATH_MAX] = {'\0'};
  std::filesystem::path full_path(kDataPath);
  WEAVE_ERROR err;
  size_t out_len;

  err = device_info_->ReadConfigValueStr(kDeviceInfoConfigKey_PrivateKeyPath, path, sizeof(path),
                                         &out_len);
  if (err != WEAVE_NO_ERROR) {
    FX_LOGS(INFO) << "No private key found";
    return ZX_ERR_NOT_FOUND;
  }
  full_path.append(path);
  if (!files::ReadFileToVector(full_path.string(), signing_key)) {
    return ZX_ERR_INTERNAL;
  }
  return ZX_OK;
}

zx_status_t ConfigurationManagerDelegateImpl::ReadFactoryFile(const char* path, char* buf,
                                                              size_t buf_size, size_t* out_len) {
  fuchsia::io::DirectorySyncPtr factory_directory;
  zx_status_t status;
  struct stat statbuf;
  int dir_fd;

  // Open the factory store directory as a file descriptor.
  status = factory_store_provider_->GetFactoryStore(factory_directory.NewRequest());
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to get factory store: " << zx_status_get_string(status);
    return status;
  }
  status = fdio_fd_create(factory_directory.Unbind().TakeChannel().release(), &dir_fd);
  if (status != ZX_OK || dir_fd < 0) {
    FX_LOGS(ERROR) << "Failed to open factory store: " << zx_status_get_string(status);
    return status;
  }

  auto close_dir_defer = fit::defer([&] { close(dir_fd); });

  // Grab the fd of the corresponding file path and validate.
  int fd = openat(dir_fd, path, O_RDONLY);
  if (fd < 0) {
    FX_LOGS(ERROR) << "Failed to open " << path << ": " << strerror(errno);
    return ZX_ERR_IO;
  }

  auto close_fd_defer = fit::defer([&] { close(fd); });

  // Check the size of the file.
  if (fstat(fd, &statbuf) < 0) {
    FX_LOGS(ERROR) << "Could not stat file: " << path << ": " << strerror(errno);
    return ZX_ERR_IO;
  }
  size_t file_size = static_cast<size_t>(statbuf.st_size);
  if (file_size > buf_size) {
    FX_LOGS(ERROR) << "File too large for buffer: File size = " << file_size
                   << ", buffer size = " << buf_size;
    return ZX_ERR_BUFFER_TOO_SMALL;
  }

  // Read up to buf_size bytes into buf.
  size_t total_read = 0;
  ssize_t current_read = 0;
  while ((current_read = read(fd, buf + total_read, buf_size - total_read)) > 0) {
    total_read += current_read;
  }

  // Store the total size read.
  if (out_len) {
    *out_len = total_read;
  }

  // Confirm that the last read was successful.
  if (current_read < 0) {
    FX_LOGS(ERROR) << "Failed to read from file: " << strerror(errno);
    status = ZX_ERR_IO;
  }

  return status;
}

zx_status_t ConfigurationManagerDelegateImpl::GetDeviceIdFromFactory(const char* path,
                                                                     uint64_t* factory_device_id) {
  zx_status_t status;
  char output[kWeaveDeviceIdMaxLength + 1] = {'\0'};

  status = ReadFactoryFile(path, output, kWeaveDeviceIdMaxLength, nullptr);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to read " << path << ": " << zx_status_get_string(status);
    return status;
  }

  if (output[0] == '\0') {
    FX_LOGS(ERROR) << "File containing device ID was empty.";
    return ZX_ERR_IO;
  }

  *factory_device_id = strtoull(output, NULL, 16);
  if (errno == ERANGE) {
    FX_LOGS(ERROR) << "Failed to strtoull device ID: " << strerror(errno);
    return ZX_ERR_IO;
  }

  return ZX_OK;
}

}  // namespace DeviceLayer
}  // namespace Weave
}  // namespace nl
