// Copyright 2014 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 "attestation/server/dbus_service.h"

#include <memory>
#include <string>
#include <utility>

#include <base/bind.h>
#include <dbus/attestation/dbus-constants.h>
#include <dbus/bus.h>
#include <dbus/object_path.h>

using brillo::dbus_utils::DBusMethodResponse;

namespace attestation {

DBusService::DBusService(const scoped_refptr<dbus::Bus>& bus,
                         AttestationInterface* service)
    : dbus_object_(nullptr, bus, dbus::ObjectPath(kAttestationServicePath)),
      service_(service) {}

void DBusService::Register(const CompletionAction& callback) {
  brillo::dbus_utils::DBusInterface* dbus_interface =
      dbus_object_.AddOrGetInterface(kAttestationInterface);

  dbus_interface->AddMethodHandler(kGetKeyInfo, base::Unretained(this),
                                   &DBusService::HandleGetKeyInfo);
  dbus_interface->AddMethodHandler(kGetEndorsementInfo, base::Unretained(this),
                                   &DBusService::HandleGetEndorsementInfo);
  dbus_interface->AddMethodHandler(kGetAttestationKeyInfo,
                                   base::Unretained(this),
                                   &DBusService::HandleGetAttestationKeyInfo);
  dbus_interface->AddMethodHandler(kActivateAttestationKey,
                                   base::Unretained(this),
                                   &DBusService::HandleActivateAttestationKey);
  dbus_interface->AddMethodHandler(kCreateCertifiableKey,
                                   base::Unretained(this),
                                   &DBusService::HandleCreateCertifiableKey);
  dbus_interface->AddMethodHandler(kDecrypt, base::Unretained(this),
                                   &DBusService::HandleDecrypt);
  dbus_interface->AddMethodHandler(kSign, base::Unretained(this),
                                   &DBusService::HandleSign);
  dbus_interface->AddMethodHandler(
      kRegisterKeyWithChapsToken, base::Unretained(this),
      &DBusService::HandleRegisterKeyWithChapsToken);
  dbus_interface->AddMethodHandler(
      kGetEnrollmentPreparations, base::Unretained(this),
      &DBusService::HandleGetEnrollmentPreparations);
  dbus_interface->AddMethodHandler(kGetStatus, base::Unretained(this),
                                   &DBusService::HandleGetStatus);
  dbus_interface->AddMethodHandler(kVerify, base::Unretained(this),
                                   &DBusService::HandleVerify);
  dbus_interface->AddMethodHandler(kCreateEnrollRequest, base::Unretained(this),
                                   &DBusService::HandleCreateEnrollRequest);
  dbus_interface->AddMethodHandler(kFinishEnroll, base::Unretained(this),
                                   &DBusService::HandleFinishEnroll);
  dbus_interface->AddMethodHandler(kEnroll, base::Unretained(this),
                                   &DBusService::HandleEnroll);
  dbus_interface->AddMethodHandler(
      kCreateCertificateRequest, base::Unretained(this),
      &DBusService::HandleCreateCertificateRequest);
  dbus_interface->AddMethodHandler(
      kFinishCertificateRequest, base::Unretained(this),
      &DBusService::HandleFinishCertificateRequest);
  dbus_interface->AddMethodHandler(kGetCertificate, base::Unretained(this),
                                   &DBusService::HandleGetCertificate);
  dbus_interface->AddMethodHandler(kSignEnterpriseChallenge,
                                   base::Unretained(this),
                                   &DBusService::HandleSignEnterpriseChallenge);
  dbus_interface->AddMethodHandler(kSignSimpleChallenge, base::Unretained(this),
                                   &DBusService::HandleSignSimpleChallenge);
  dbus_interface->AddMethodHandler(kSetKeyPayload, base::Unretained(this),
                                   &DBusService::HandleSetKeyPayload);
  dbus_interface->AddMethodHandler(kDeleteKeys, base::Unretained(this),
                                   &DBusService::HandleDeleteKeys);
  dbus_interface->AddMethodHandler(kResetIdentity, base::Unretained(this),
                                   &DBusService::HandleResetIdentity);
  dbus_interface->AddMethodHandler(kGetEnrollmentId, base::Unretained(this),
                                   &DBusService::HandleGetEnrollmentId);
  dbus_interface->AddMethodHandler(kGetCertifiedNvIndex, base::Unretained(this),
                                   &DBusService::HandleGetCertifiedNvIndex);

  dbus_object_.RegisterAsync(callback);
}

void DBusService::HandleGetKeyInfo(
    std::unique_ptr<DBusMethodResponse<const GetKeyInfoReply&>> response,
    const GetKeyInfoRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const GetKeyInfoReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const GetKeyInfoReply& reply) { response->Return(reply); };
  service_->GetKeyInfo(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleGetEndorsementInfo(
    std::unique_ptr<DBusMethodResponse<const GetEndorsementInfoReply&>>
        response,
    const GetEndorsementInfoRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const GetEndorsementInfoReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const GetEndorsementInfoReply& reply) {
    response->Return(reply);
  };
  service_->GetEndorsementInfo(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleGetAttestationKeyInfo(
    std::unique_ptr<DBusMethodResponse<const GetAttestationKeyInfoReply&>>
        response,
    const GetAttestationKeyInfoRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const GetAttestationKeyInfoReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const GetAttestationKeyInfoReply& reply) {
    response->Return(reply);
  };
  service_->GetAttestationKeyInfo(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleActivateAttestationKey(
    std::unique_ptr<DBusMethodResponse<const ActivateAttestationKeyReply&>>
        response,
    const ActivateAttestationKeyRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const ActivateAttestationKeyReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const ActivateAttestationKeyReply& reply) {
    response->Return(reply);
  };
  service_->ActivateAttestationKey(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleCreateCertifiableKey(
    std::unique_ptr<DBusMethodResponse<const CreateCertifiableKeyReply&>>
        response,
    const CreateCertifiableKeyRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const CreateCertifiableKeyReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const CreateCertifiableKeyReply& reply) {
    response->Return(reply);
  };
  service_->CreateCertifiableKey(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleDecrypt(
    std::unique_ptr<DBusMethodResponse<const DecryptReply&>> response,
    const DecryptRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const DecryptReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const DecryptReply& reply) { response->Return(reply); };
  service_->Decrypt(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleSign(
    std::unique_ptr<DBusMethodResponse<const SignReply&>> response,
    const SignRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const SignReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const SignReply& reply) { response->Return(reply); };
  service_->Sign(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleRegisterKeyWithChapsToken(
    std::unique_ptr<DBusMethodResponse<const RegisterKeyWithChapsTokenReply&>>
        response,
    const RegisterKeyWithChapsTokenRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer = std::shared_ptr<
      DBusMethodResponse<const RegisterKeyWithChapsTokenReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const RegisterKeyWithChapsTokenReply& reply) {
    response->Return(reply);
  };
  service_->RegisterKeyWithChapsToken(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleGetEnrollmentPreparations(
    std::unique_ptr<DBusMethodResponse<const GetEnrollmentPreparationsReply&>>
        response,
    const GetEnrollmentPreparationsRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer = std::shared_ptr<
      DBusMethodResponse<const GetEnrollmentPreparationsReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const GetEnrollmentPreparationsReply& reply) {
    response->Return(reply);
  };
  service_->GetEnrollmentPreparations(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleGetStatus(
    std::unique_ptr<DBusMethodResponse<const GetStatusReply&>> response,
    const GetStatusRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const GetStatusReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const GetStatusReply& reply) { response->Return(reply); };
  service_->GetStatus(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleVerify(
    std::unique_ptr<DBusMethodResponse<const VerifyReply&>> response,
    const VerifyRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const VerifyReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const VerifyReply& reply) { response->Return(reply); };
  service_->Verify(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleCreateEnrollRequest(
    std::unique_ptr<DBusMethodResponse<const CreateEnrollRequestReply&>>
        response,
    const CreateEnrollRequestRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const CreateEnrollRequestReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const CreateEnrollRequestReply& reply) {
    response->Return(reply);
  };
  service_->CreateEnrollRequest(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleFinishEnroll(
    std::unique_ptr<DBusMethodResponse<const FinishEnrollReply&>> response,
    const FinishEnrollRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const FinishEnrollReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const FinishEnrollReply& reply) {
    response->Return(reply);
  };
  service_->FinishEnroll(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleEnroll(
    std::unique_ptr<DBusMethodResponse<const EnrollReply&>> response,
    const EnrollRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const EnrollReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const EnrollReply& reply) { response->Return(reply); };
  service_->Enroll(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleCreateCertificateRequest(
    std::unique_ptr<DBusMethodResponse<const CreateCertificateRequestReply&>>
        response,
    const CreateCertificateRequestRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const CreateCertificateRequestReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const CreateCertificateRequestReply& reply) {
    response->Return(reply);
  };
  service_->CreateCertificateRequest(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleFinishCertificateRequest(
    std::unique_ptr<DBusMethodResponse<const FinishCertificateRequestReply&>>
        response,
    const FinishCertificateRequestRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const FinishCertificateRequestReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const FinishCertificateRequestReply& reply) {
    response->Return(reply);
  };
  service_->FinishCertificateRequest(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleGetCertificate(
    std::unique_ptr<DBusMethodResponse<const GetCertificateReply&>> response,
    const GetCertificateRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const GetCertificateReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const GetCertificateReply& reply) {
    response->Return(reply);
  };
  service_->GetCertificate(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleSignEnterpriseChallenge(
    std::unique_ptr<DBusMethodResponse<const SignEnterpriseChallengeReply&>>
        response,
    const SignEnterpriseChallengeRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const SignEnterpriseChallengeReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const SignEnterpriseChallengeReply& reply) {
    response->Return(reply);
  };
  service_->SignEnterpriseChallenge(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleSignSimpleChallenge(
    std::unique_ptr<DBusMethodResponse<const SignSimpleChallengeReply&>>
        response,
    const SignSimpleChallengeRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const SignSimpleChallengeReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const SignSimpleChallengeReply& reply) {
    response->Return(reply);
  };
  service_->SignSimpleChallenge(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleSetKeyPayload(
    std::unique_ptr<DBusMethodResponse<const SetKeyPayloadReply&>> response,
    const SetKeyPayloadRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const SetKeyPayloadReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const SetKeyPayloadReply& reply) {
    response->Return(reply);
  };
  service_->SetKeyPayload(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleDeleteKeys(
    std::unique_ptr<DBusMethodResponse<const DeleteKeysReply&>> response,
    const DeleteKeysRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const DeleteKeysReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const DeleteKeysReply& reply) { response->Return(reply); };
  service_->DeleteKeys(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleResetIdentity(
    std::unique_ptr<DBusMethodResponse<const ResetIdentityReply&>> response,
    const ResetIdentityRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const ResetIdentityReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const ResetIdentityReply& reply) {
    response->Return(reply);
  };
  service_->ResetIdentity(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleGetEnrollmentId(
    std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
        const GetEnrollmentIdReply&>> response,
    const GetEnrollmentIdRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const GetEnrollmentIdReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const GetEnrollmentIdReply& reply) {
    response->Return(reply);
  };
  service_->GetEnrollmentId(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

void DBusService::HandleGetCertifiedNvIndex(
    std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<
        const GetCertifiedNvIndexReply&>> response,
    const GetCertifiedNvIndexRequest& request) {
  VLOG(1) << __func__;
  // Convert |response| to a shared_ptr so |service_| can safely copy the
  // callback.
  using SharedResponsePointer =
      std::shared_ptr<DBusMethodResponse<const GetCertifiedNvIndexReply&>>;
  // A callback that fills the reply protobuf and sends it.
  auto callback = [](const SharedResponsePointer& response,
                     const GetCertifiedNvIndexReply& reply) {
    response->Return(reply);
  };
  service_->GetCertifiedNvIndex(
      request,
      base::Bind(callback, SharedResponsePointer(std::move(response))));
}

}  // namespace attestation
