// gpowerd is the safe power local agent for BMC.
// It implements the SafePowerLocalAgent service, and is responsible for
// actuating power cycles on the machine.

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

#include "action_context.h"
#include "bmc/auth.h"
#include "bmc/daemon_context_bmc.h"
#include "bmc/machine_configs/setup_configs.h"
#include "bmc/state_monitor_bmc.h"
#include "safepower_agent_config.pb.h"
#include "safepower_agent.h"
#include "state_updater.h"
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/log/globals.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "grpc/support/time.h"
#include "grpcpp/ext/proto_server_reflection_plugin.h"
#include "grpcpp/security/authorization_policy_provider.h"
#include "grpcpp/security/server_credentials.h"
#include "grpcpp/server.h"
#include "grpcpp/server_builder.h"
#include "bmc/status_macros.h"

using grpc::Server;
using grpc::ServerBuilder;
using safepower_agent::DaemonContextBMC;
using safepower_agent::SafepowerLocalAgentImpl;
using safepower_agent::StateUpdater;


using ::grpc::experimental::AuthorizationPolicyProviderInterface;

const char* address = "[::]:20120";

// The built-in log flags are not being pulled into this code because the cmake
// build does not include the flags library for logging, so a local flag was
// setup to mitigate this.

// Global log verbosity level. Default is 0.
ABSL_FLAG(int, v, 0, "Global log verbosity level").OnUpdate([] {
  absl::SetGlobalVLogLevel(absl::GetFlag(FLAGS_v));
});

absl::Status main_gpowerd() {
  DaemonContextBMC daemon_context;
  safepower_agent_proto::SystemState initialState;
  auto reactor =
      std::make_shared<StateUpdater<safepower_agent_proto::SystemState>>(
          std::move(initialState), true);
  auto action_context_manager =
      std::make_unique<safepower_agent::ActionContextManager>(reactor);

  auto state_monitor =
      std::make_shared<safepower_agent::StateMonitorBMC>(reactor);

  RETURN_IF_ERROR(
      setup_configs::SetupConfigs(*state_monitor, *action_context_manager));

  SafepowerLocalAgentImpl safePowerService(std::move(reactor),
                                           std::move(action_context_manager));
  ServerBuilder builder;

  std::shared_ptr<grpc::ServerCredentials> creds = nullptr;
#ifdef INSECURE_MODE
  creds = grpc::InsecureServerCredentials();  // NOLINT if the image is
  //  build in insecure mode, build the grpc server with
  //  insecure credentials
  LOG(WARNING) << "Using insecure credentials";
#else
  LOG(INFO) << "Using secure credentials";

  ASSIGN_OR_RETURN(creds, auth::GetCredsInfo());

  LOG(INFO) << "Credentials loaded";
  ASSIGN_OR_RETURN(std::shared_ptr<AuthorizationPolicyProviderInterface> policy,
                   auth::GetAuthPolicy());
  LOG(INFO) << "authorization policy loaded";
  builder.experimental().SetAuthorizationPolicyProvider(policy);
#endif  // INSECURE_MODE

  LOG(INFO) << "using address " << address;
  builder.AddListeningPort(address, creds);

  /* Listen on the given address with an authentication mechanism. */
  builder.RegisterService(&safePowerService);
  grpc::reflection::InitProtoReflectionServerBuilderPlugin();

  std::unique_ptr<Server> server(builder.BuildAndStart());
  if (server == nullptr) {
    // TODO Add logic to restarting safePowerService, while running events
    // in the scheduler. (Possibly schedule a retry.)
    LOG(ERROR) << "grpc server failed to start, exiting gPowerD";
    return absl::InternalError("grpc server failed to start, exiting gPowerD");
  }

  // register SIGTERM handler before starting io loop
  std::signal(SIGTERM, [](int) {
    LOG(INFO) << "Received SIGTERM, starting shutting down gracefully";

    absl::Status status = DaemonContextBMC::Get().scheduler().Shutdown();
    if (!status.ok()) {
      LOG(ERROR) << "SIGTERM, shutting down error : " << status;
    }
  });

  LOG(INFO) << "gPowerD started";
  DaemonContextBMC::Get().get_io_context().run();
  LOG(INFO) << "event loop returned";
  if (server) {
    server->Shutdown(gpr_now(GPR_CLOCK_MONOTONIC));
  }
  LOG(INFO) << "gPowerD stopped; grpc server shutdown";
  return absl::OkStatus();
}

int main(int argc, char** argv) {
  absl::ParseCommandLine(argc, argv);
  absl::Status status = main_gpowerd();
  if (!status.ok()) {
    LOG(ERROR) << "gpowerd exited with status: " << status;
    return 1;
  }
  LOG(INFO) << "gpowerd exited with status: 0 ";
  return 0;
}
