// 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.

// See help usage message in main() for basic description.

#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>

#include <brillo/flag_helper.h>

#include "diagnostics/dpsl/public/dpsl_global_context.h"
#include "diagnostics/dpsl/public/dpsl_rpc_handler.h"
#include "diagnostics/dpsl/public/dpsl_rpc_server.h"
#include "diagnostics/dpsl/public/dpsl_thread_context.h"
#include "diagnostics/dpsl/test_utils/common.h"

#include "wilco_dtc.pb.h"  // NOLINT(build/include)
#include "wilco_dtc_supportd.pb.h"  // NOLINT(build/include)

namespace diagnostics {
namespace {

class DpslTestListener final : public DpslRpcHandler {
 public:
  DpslTestListener(
      std::unique_ptr<grpc_api::HandleMessageFromUiResponse> ui_response) {
    ui_response_ = std::move(ui_response);
  }

  // DpslRpcHandler overrides:
  void HandleMessageFromUi(
      std::unique_ptr<grpc_api::HandleMessageFromUiRequest> request,
      HandleMessageFromUiCallback callback) override {
    test_utils::PrintProto(*request);
    // Note: every incoming RPC must be answered.
    callback(
        std::make_unique<grpc_api::HandleMessageFromUiResponse>(*ui_response_));
  };

  void HandleEcNotification(
      std::unique_ptr<grpc_api::HandleEcNotificationRequest> request,
      HandleEcNotificationCallback callback) override {
    test_utils::PrintProto(*request);
    // Note: every incoming RPC must be answered.
    callback(std::make_unique<grpc_api::HandleEcNotificationResponse>());
  };

  void HandlePowerNotification(
      std::unique_ptr<grpc_api::HandlePowerNotificationRequest> request,
      HandlePowerNotificationCallback callback) override {
    test_utils::PrintProto(*request);
    // Note: every incoming RPC must be answered.
    callback(std::make_unique<grpc_api::HandlePowerNotificationResponse>());
  };

  void HandleConfigurationDataChanged(
      std::unique_ptr<grpc_api::HandleConfigurationDataChangedRequest> request,
      HandleConfigurationDataChangedCallback callback) override {
    test_utils::PrintProto(*request);
    // Note: every incoming RPC must be answered.
    callback(
        std::make_unique<grpc_api::HandleConfigurationDataChangedResponse>());
  };

  void HandleBluetoothDataChanged(
      std::unique_ptr<grpc_api::HandleBluetoothDataChangedRequest> request,
      HandleBluetoothDataChangedCallback callback) override {
    test_utils::PrintProto(*request);
    // Note: every incoming RPC must be answered.
    callback(std::make_unique<grpc_api::HandleBluetoothDataChangedResponse>());
  };

 private:
  std::unique_ptr<grpc_api::HandleMessageFromUiResponse> ui_response_;
};

}  // namespace
}  // namespace diagnostics

int main(int argc, char** argv) {
  DEFINE_string(ui_response_body, "",
                "optional JSON-formatted body of proto to send as the response "
                "to HandleMessageFromUi");
  constexpr char kUsageMessage[] =
      R"(DPSL Listener Utility
Command line utility to test DPSL communication into and out of a VM. The
utility blocks indefinitely, monitoring and printing any incoming gRPC requests
from wilco_dtc_supportd. The request is printed as JSON, so you can see both the
name and the actual content of the proto.

EXAMPLE USAGE
(VM)$ diagnostics_dpsl_test_listener \
  --ui_response_body='{"response_json_message": "{test: 1}"}'
...THEN YOU FORCE THE EC TO GENERATE AN EVENT...
{
   "body": {
      "type": 19,
      "payload":"AAABAAIAAwAEAAUA"
   },
   "name": "HandleEcNotificationRequest"
})";
  brillo::FlagHelper::Init(argc, argv, kUsageMessage);

  std::unique_ptr<diagnostics::grpc_api::HandleMessageFromUiResponse>
      ui_response;
  if (!FLAGS_ui_response_body.empty()) {
    ui_response = diagnostics::test_utils::JsonToProto<
        diagnostics::grpc_api::HandleMessageFromUiResponse>(
        FLAGS_ui_response_body);

    if (!ui_response) {
      std::cerr << "Failed to parse ui_response_body\n";
      return EXIT_FAILURE;
    }
  } else {
    ui_response =
        std::make_unique<diagnostics::grpc_api::HandleMessageFromUiResponse>();
  }

  auto global_context = diagnostics::DpslGlobalContext::Create();
  auto thread_context =
      diagnostics::DpslThreadContext::Create(global_context.get());
  diagnostics::DpslTestListener listener(std::move(ui_response));
  auto rpc_server = diagnostics::DpslRpcServer::Create(
      thread_context.get(), &listener,
      diagnostics::DpslRpcServer::GrpcServerUri::kUiMessageReceiverVmVsock);
  if (!rpc_server) {
    std::cerr << "Failed to create DpslRpcServer\n";
    return EXIT_FAILURE;
  }

  // This blocks forever, responding to any incoming gRPC requests.
  thread_context->RunEventLoop();

  return EXIT_SUCCESS;
}
