// 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 kErrorCodeProfileNotEnabled[] = "ProfileNotEnabled";
const char kErrorCodeNeedConfirmationCode[] = "NeedConfirmationCode";
const char kErrorCodeInvalidActivationCode[] = "InvalidActivationCode";
const char kErrorCodeSendNotificationError[] = "SendNotificationError";

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::kProfileNotEnabled] = brillo::Error::Create(
      FROM_HERE, kErrorDomain, kErrorCodeProfileNotEnabled,
      "Requested method needs an enabled 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");
}

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;
  }

  auto simple_cb = [response{std::shared_ptr<DBusResponse<ProfileInfo>>(
                        std::move(response))},
                    cb{std::move(profile_cb)}, in_activation_code,
                    this](int error) {
    if (!HandleLpaError(error, &error_map_, response.get())) {
      return;
    }
    // TODO(crbug.com/963555) Return valid ProfileInfo
    lpa::proto::ProfileInfo empty;
    cb(empty, error);
  };
  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(simple_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
