// Copyright 2019 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 "hermes/dbus_adaptor.h"

#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/callback.h>
#include <chromeos/dbus/service_constants.h>
#include <google-lpa/lpa/core/lpa.h>

namespace {

const char kErrorDomain[] = "Hermes";

const char kErrorCodeUnknown[] = "Unknown";
const char kErrorCodeWrongState[] = "WrongState";
const char kErrorCodeInvalidIccid[] = "InvalidIccid";
const char kErrorCodeProfileAlreadyEnabled[] = "ProfileAlreadyEnabled";
const char kErrorCodeProfileAlreadyDisabled[] = "ProfileAlreadyDisabled";
const char kErrorCodeNeedConfirmationCode[] = "NeedConfirmationCode";
const char kErrorCodeInvalidActivationCode[] = "InvalidActivationCode";
const char kErrorCodeSendNotificationError[] = "SendNotificationError";
const char kErrorCodeNoOpForTestingProfile[] = "NoOpForTestingProfile";

bool HandleLpaError(
    int error,
    const std::map<int, std::unique_ptr<brillo::Error>>* error_map,
    brillo::dbus_utils::DBusMethodResponseBase* response) {
  CHECK(error_map);
  if (error != lpa::core::Lpa::kNoError) {
    auto iter = error_map->find(error);
    if (iter != error_map->end()) {
      response->ReplyWithError(iter->second.get());
    } else {
      response->ReplyWithError(FROM_HERE, kErrorDomain, kErrorCodeUnknown,
                               "Unknown error");
    }
    return false;
  }
  return true;
}

// Function to return from a D-Bus hermes method that has no output parameters.
//
// Note the use of a shared_ptr rather than unique_ptr. The google-lpa API takes
// std::function parameters as callbacks. Since the standard states that
// std::functions must be CopyConstructible, bind states or lambdas that gain
// ownership of a unique_ptr may not be used as a std::function. As the
// org::chromium::HermesInterface interface is passed a unique_ptr, the options
// are either to maintain DBusMethodResponse lifetimes separately or to convert
// unique_ptrs to shared_ptrs.
void DefaultCallback(
    const std::map<int, std::unique_ptr<brillo::Error>>* error_map,
    std::shared_ptr<brillo::dbus_utils::DBusMethodResponse<>> response,
    int error) {
  if (!HandleLpaError(error, error_map, response.get())) {
    return;
  }
  response->Return();
}

}  // namespace

namespace hermes {

using lpa::proto::ProfileInfo;
using lpa::proto::ProfileInfoList;

DBusAdaptor::DBusAdaptor(lpa::core::Lpa* lpa, Executor* executor)
    : org::chromium::HermesAdaptor(this), lpa_(lpa), executor_(executor) {
  // Create mapping from google-lpa error to brillo error.
  error_map_[lpa::core::Lpa::kWrongState] =
      brillo::Error::Create(FROM_HERE, kErrorDomain, kErrorCodeWrongState,
                            "Invalid state for requested method");
  error_map_[lpa::core::Lpa::kIccidNotFound] = brillo::Error::Create(
      FROM_HERE, kErrorDomain, kErrorCodeInvalidIccid, "Invalid iccid");
  error_map_[lpa::core::Lpa::kProfileAlreadyEnabled] = brillo::Error::Create(
      FROM_HERE, kErrorDomain, kErrorCodeProfileAlreadyEnabled,
      "Requested method provided an already-enabled profile");
  error_map_[lpa::core::Lpa::kProfileAlreadyDisabled] = brillo::Error::Create(
      FROM_HERE, kErrorDomain, kErrorCodeProfileAlreadyDisabled,
      "Requested method provided a disabled profile");
  error_map_[lpa::core::Lpa::kNeedConfirmationCode] = brillo::Error::Create(
      FROM_HERE, kErrorDomain, kErrorCodeNeedConfirmationCode,
      "Need confirmation code");
  error_map_[lpa::core::Lpa::kInvalidActivationCode] = brillo::Error::Create(
      FROM_HERE, kErrorDomain, kErrorCodeInvalidActivationCode,
      "Invalid activation code");
  error_map_[lpa::core::Lpa::kFailedToSendNotifications] =
      brillo::Error::Create(FROM_HERE, kErrorDomain,
                            kErrorCodeSendNotificationError,
                            "Failed to send notifications");
  error_map_[lpa::core::Lpa::kNoOpForTestingProfile] = brillo::Error::Create(
      FROM_HERE, kErrorDomain, kErrorCodeNoOpForTestingProfile,
      "Non-test mode cannot use test profile");
}

void DBusAdaptor::InstallProfile(
    std::unique_ptr<DBusResponse<ProfileInfo>> response,
    const std::string& in_activation_code) {
  auto profile_cb = [response{std::shared_ptr<DBusResponse<ProfileInfo>>(
                         std::move(response))},
                     this](lpa::proto::ProfileInfo& profile, int error) {
    if (!HandleLpaError(error, &error_map_, response.get())) {
      return;
    }
    response->Return(profile);
  };
  if (in_activation_code.empty()) {
    lpa_->GetDefaultProfileFromSmdp("", executor_, std::move(profile_cb));
    return;
  }

  lpa::core::Lpa::DownloadOptions options;
  options.enable_profile = false;
  options.allow_policy_rules = false;
  lpa_->DownloadProfile(in_activation_code, std::move(options), executor_,
                        std::move(profile_cb));
}

void DBusAdaptor::UninstallProfile(std::unique_ptr<DBusResponse<>> response,
                                   const std::string& in_iccid) {
  lpa_->DeleteProfile(
      in_iccid, executor_,
      std::bind(&DefaultCallback, &error_map_,
                std::shared_ptr<DBusResponse<>>(std::move(response)),
                std::placeholders::_1));
}

void DBusAdaptor::EnableProfile(std::unique_ptr<DBusResponse<>> response,
                                const std::string& in_iccid) {
  lpa_->EnableProfile(
      in_iccid, executor_,
      std::bind(&DefaultCallback, &error_map_,
                std::shared_ptr<DBusResponse<>>(std::move(response)),
                std::placeholders::_1));
}

void DBusAdaptor::DisableProfile(std::unique_ptr<DBusResponse<>> response,
                                 const std::string& in_iccid) {
  lpa_->DisableProfile(
      in_iccid, executor_,
      std::bind(&DefaultCallback, &error_map_,
                std::shared_ptr<DBusResponse<>>(std::move(response)),
                std::placeholders::_1));
}

void DBusAdaptor::SetProfileNickname(std::unique_ptr<DBusResponse<>> response,
                                     const std::string& in_iccid,
                                     const std::string& in_nickname) {
  lpa_->SetProfileNickname(
      in_iccid, in_nickname, executor_,
      std::bind(&DefaultCallback, &error_map_,
                std::shared_ptr<DBusResponse<>>(std::move(response)),
                std::placeholders::_1));
}

void DBusAdaptor::GetInstalledProfiles(
    std::unique_ptr<DBusResponse<ProfileInfoList>> response) {
  auto cb = [response{std::shared_ptr<DBusResponse<ProfileInfoList>>(
                 std::move(response))},
             this](std::vector<lpa::proto::ProfileInfo>& profiles, int error) {
    if (!HandleLpaError(error, &error_map_, response.get())) {
      return;
    }

    ProfileInfoList profile_list;
    VLOG(2) << "Installed profiles:";
    for (auto profile : profiles) {
      *profile_list.add_profile_info() = profile;

      VLOG(2) << "";
      VLOG(2) << "    ICCID: " << profile.iccid();
      VLOG_IF(2, profile.has_activation_code())
          << "    Activation code: " << profile.activation_code();
      VLOG_IF(2, profile.has_profile_name())
          << "    Profile name: " << profile.profile_name();
    }
    response->Return(profile_list);
  };
  lpa_->GetInstalledProfiles(executor_, std::move(cb));
}

void DBusAdaptor::SetTestMode(bool /*in_is_test_mode*/) {
  // TODO(akhouderchah) This is a no-op until the Lpa interface allows for
  // switching certificate directory without recreating the Lpa object.
  NOTIMPLEMENTED();
}

}  // namespace hermes
