// Copyright 2020 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/manager.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>

#include "hermes/lpa_util.h"

using lpa::proto::ProfileInfo;

namespace hermes {

namespace {

const char kHermesErrorDomain[] = "Hermes";

}  // namespace

Manager::Manager(const scoped_refptr<dbus::Bus>& bus, LpaContext* context)
    : org::chromium::Hermes::ManagerAdaptor(this),
      bus_(bus),
      dbus_object_(nullptr,
                   bus_,
                   org::chromium::Hermes::ManagerAdaptor::GetObjectPath()),
      context_(context) {
  RegisterWithDBusObject(&dbus_object_);
  dbus_object_.RegisterAndBlock();

  RetrieveInstalledProfiles();
}

void Manager::InstallProfileFromActivationCode(
    std::unique_ptr<DBusResponse<dbus::ObjectPath>> response,
    const std::string& in_activation_code) {
  auto profile_cb = [response{std::shared_ptr<DBusResponse<dbus::ObjectPath>>(
                         std::move(response))},
                     this](lpa::proto::ProfileInfo& profile, int error) {
    auto decoded_error = LpaErrorToBrillo(FROM_HERE, error);
    if (decoded_error) {
      response->ReplyWithError(decoded_error.get());
      return;
    }
    profiles_.push_back(std::make_unique<Profile>(bus_, context_, profile));
    UpdateProfilesProperty();
    response->Return(profiles_.back()->object_path());
  };
  if (in_activation_code.empty()) {
    context_->lpa->GetDefaultProfileFromSmdp("", context_->executor,
                                             std::move(profile_cb));
    return;
  }

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

void Manager::InstallProfileFromEvent(
    std::unique_ptr<DBusResponse<dbus::ObjectPath>> response,
    const std::string& /*in_smdp_address*/,
    const std::string& /*in_event_id*/) {
  response->ReplyWithError(
      FROM_HERE, kHermesErrorDomain, "UnsupportedMethod",
      "This method is not supported until crbug.com/1071470 is implemented");
}

void Manager::UninstallProfile(std::unique_ptr<DBusResponse<>> response,
                               const dbus::ObjectPath& in_profile) {
  const Profile* matching_profile = nullptr;
  for (auto& profile : profiles_) {
    if (profile->object_path() == in_profile) {
      matching_profile = profile.get();
      break;
    }
  }
  if (!matching_profile) {
    response->ReplyWithError(FROM_HERE, kHermesErrorDomain, "InvalidParameter",
                             "Could not find Profile " + in_profile.value());
    return;
  }

  // Wait for lpa call to complete successfully before removing element from
  // |profiles_|.
  auto profile_cb =
      [response{std::shared_ptr<DBusResponse<>>(std::move(response))},
       in_profile, this](int error) {
        auto decoded_error = LpaErrorToBrillo(FROM_HERE, error);
        if (decoded_error) {
          response->ReplyWithError(decoded_error.get());
          return;
        }

        auto iter = std::find_if(profiles_.begin(), profiles_.end(),
                                 [in_profile](const auto& profile) {
                                   return profile->object_path() == in_profile;
                                 });
        CHECK(iter != profiles_.end());
        profiles_.erase(iter);
        UpdateProfilesProperty();
        response->Return();
      };
  context_->lpa->DeleteProfile(matching_profile->GetIccid(), context_->executor,
                               std::move(profile_cb));
}

void Manager::RequestPendingEvents(
    std::unique_ptr<DBusResponse<std::vector<Event>>> response) {
  // TODO(crbug.com/1071470) This is stubbed until google-lpa supports SM-DS.
  response->Return({});
}

void Manager::UpdateProfilesProperty() {
  std::vector<dbus::ObjectPath> profile_paths;
  for (auto& profile : profiles_) {
    profile_paths.push_back(profile->object_path());
  }
  SetProfiles(profile_paths);
}

void Manager::RetrieveInstalledProfiles() {
  auto cb = [this](std::vector<lpa::proto::ProfileInfo>& profiles, int error) {
    auto decoded_error = LpaErrorToBrillo(FROM_HERE, error);
    if (decoded_error) {
      LOG(ERROR) << "Failed to retrieve installed profiles";
      return;
    }

    for (auto& profile : profiles) {
      profiles_.push_back(std::make_unique<Profile>(bus_, context_, profile));
    }
    UpdateProfilesProperty();
  };
  context_->lpa->GetInstalledProfiles(context_->executor, std::move(cb));
}

void Manager::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
