#include "service_impl.h"

#include <memory>
#include <ostream>

#include "action_context.h"
#include "daemon_context.h"
#include "safepower_agent.pb.h"
#include "state_updater.h"
#include "absl/base/nullability.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/time/time.h"

namespace safepower_agent {

absl::Status ServiceImpl::CheckDisruption() const {
  absl::Duration disruption =
      DaemonContext::Get().disruption_manager().PendingDisruption();
  if (disruption > absl::ZeroDuration()) {
    LOG(WARNING) << "Failing RPC because disruption is expected in "
                 << disruption;
    return absl::FailedPreconditionError(absl::StrCat(
        "New operations not allowed because disruption is expected in ",
        absl::FormatDuration(disruption)));
  }
  return absl::OkStatus();
}

void ServiceImpl::DumpSafepowerState(std::ostream& os) const {
  os << "--- SafepowerLocalAgentImpl State ---" << std::endl;
  action_context_manager_->DumpDebugInfo(os);
  os << "--- System State ---" << std::endl;
  os << system_state_updater_->state().DebugString() << std::endl;
  os << "--- Global System State ---" << std::endl;
  os << global_system_state_updater_->state().DebugString() << std::endl;
  os << "--- End SafepowerLocalAgentImpl State ---" << std::endl;
}
absl::Status ServiceImpl::StartAction(
      const safepower_agent_proto::StartActionRequest& request) {
  if (auto status = CheckDisruption(); !status.ok()) return status;
  absl::StatusOr<ActionContext* > action_context =
      action_context_manager_->StartAction(request);
  if (!action_context.ok()) {
    LOG(ERROR) << "Failed to start action: " << action_context.status();
    return action_context.status();
  }
  LOG(INFO) << "Started action from request: " << request.DebugString();
  return absl::OkStatus();
}

absl::StatusOr<
    std::shared_ptr<StateUpdater<safepower_agent_proto::ActionStateLog>>>
ServiceImpl::MonitorAction(
    const safepower_agent_proto::MonitorActionRequest& request) {
  if (auto status = CheckDisruption(); !status.ok()) return status;

  ActionContext*  action_context =
      action_context_manager_->GetActionContext(request.flight_record());
  if (action_context == nullptr) {
    if (action_context_manager_->IsActionReloading(request.flight_record())) {
      LOG(INFO) << "Action flight_record: "
                << request.flight_record().DebugString()
                << " is still reloading";
      return absl::UnavailableError(
          "Action is still being reloaded during startup");
    }
    LOG(ERROR) << "Action flight_record: "
               << request.flight_record().DebugString() << " not found";
    return absl::NotFoundError(absl::StrCat(
        "Action flight_id: ", request.flight_record().flight_name(),
        " step_id: ", request.flight_record().step_id(), " not found"));
  }
  return action_context->action_state_updater();
}

absl::StatusOr<
    std::shared_ptr<StateUpdater<safepower_agent_proto::SystemState>>>
ServiceImpl::MonitorState() {
  if (auto status = CheckDisruption(); !status.ok()) return status;
  return system_state_updater_;
}

absl::Status ServiceImpl::SystemStateUpdate(
    const safepower_agent_proto::SystemState& request) {
  if (auto status = CheckDisruption(); !status.ok()) return status;
  global_system_state_updater_->UpdateState(request);
  return absl::OkStatus();
}

void ServiceImpl::GetSupportedActions(
    safepower_agent_proto::GetSupportedActionsResponse& response) {
  action_context_manager_->GetSupportedActions(response);
}

}  // namespace safepower_agent
