#include "tlbmc/hal/shared_mem/server.h"

#include <cstdint>
#include <filesystem>  // NOLINT
#include <limits>
#include <memory>
#include <string>
#include <string_view>
#include <utility>

#include "absl/base/no_destructor.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
#include "tlbmc/hal/shared_mem/metrics.h"
#include "tlbmc/hal/shared_mem/segment_manager.h"
#include "tlbmc/hal/shared_mem/sensors.h"

namespace milotic_tlbmc {

void SharedMemoryServer::Initialize() { return Initialize(""); }

void SharedMemoryServer::SetUpInstanceForUnitTest() {
  // Remove the shared memory object and the initialized file to ensure a clean
  // state for unit tests.
  if (!boost::interprocess::shared_memory_object::remove("TlbmcSharedMemory")) {
    LOG(WARNING) << "Shared memory object not removed successfully.";
  } else {
    LOG(INFO) << "Shared memory object removed successfully.";
  }

  if (!std::filesystem::remove("/tmp/tlbmc/tlbmc_shared_memory")) {
    LOG(WARNING) << "Shared memory flag file /tmp/tlbmc/tlbmc_shared_memory "
                    "was not removed successfully.";
  } else {
    LOG(INFO) << "Shared memory flag file /tmp/tlbmc/tlbmc_shared_memory was "
                 "removed.";
  }
  GetInstance("/tmp/tlbmc/tlbmc_shared_memory");
}

void SharedMemoryServer::Initialize(const std::string& initialized_file_path) {
  SharedMemoryServer::GetInstance(initialized_file_path);
}

IpcServer& SharedMemoryServer::GetInstance(
    const std::string& initialized_file_path) {
  static absl::NoDestructor<SharedMemoryServer> instance(
      Token(), initialized_file_path,
      initialized_file_path.empty()
          ? SegmentManager::Create()
          : SegmentManager::Create(initialized_file_path));
  return *instance;
}

IpcServer& SharedMemoryServer::GetInstance() { return GetInstance(""); }

SharedMemoryServer::SharedMemoryServer(
    Token token, const std::string& initialized_file_path,
    std::unique_ptr<SegmentManager> segment_manager)
    : initialized_file_path_(std::string{initialized_file_path}),
      segment_manager_(std::move(segment_manager)),
      metrics_(segment_manager_ == nullptr
                   ? nullptr
                   : segment_manager_->GetOrCreateMetrics()) {
  if (segment_manager_ == nullptr) {
    LOG(FATAL) << "SharedMemoryServer segment_manager is nullptr. This should "
                  "never happen in server side. Check the initialization log.";
  }
}

SharedMemoryServer::SharedMemoryServer(
    const std::string& initialized_file_path,
    std::unique_ptr<SegmentManager> segment_manager)
    : SharedMemoryServer(Token(), initialized_file_path,
                         std::move(segment_manager)) {}

IpcSensor* SharedMemoryServer::GetSensor(const std::string& sensor_name) {
  absl::MutexLock lock(&sensors_mutex_);
  auto it = sensors_.find(sensor_name);
  if (it != sensors_.end()) {
    return it->second;
  }
  DLOG(INFO) << "SharedMemoryServer segment_manager: "
             << segment_manager_.get();
  IpcSensor* sensor = segment_manager_->GetOrCreateSensor(sensor_name.c_str());
  DLOG(INFO) << "SharedMemoryServer sensor for " << sensor_name << ": "
             << sensor;
  sensors_[sensor_name] = sensor;
  return sensor;
}

absl::StatusOr<std::pair<float, uint64_t>> SharedMemoryServer::ReadSensorValue(
    const std::string& sensor_name) {
  IpcSensor* sensor = GetSensor(sensor_name);
  if (sensor == nullptr) {
    return absl::InternalError(
        "Failed to get sensor. This normally should not happen.");
  }

  std::pair<float, uint64_t> value = sensor->GetValue();

  // If the sensor value is not updated by the client, the value will be set to
  // infinity and the timestamp will be 0.
  if (value.first == std::numeric_limits<float>::infinity() ||
      value.second == 0) {
    return absl::UnavailableError(
        "Sensor value is still invalid due to no update from client.");
  }
  return value;
}

// copybara:strip_begin(g3-shared-libs)
void SharedMemoryServer::UpdateMetricsRequestCount(bool is_tlbmc_request) {
  if (metrics_ == nullptr) {
    return;
  }
  metrics_->UpdateMetricsRequestCount(is_tlbmc_request);
}

void SharedMemoryServer::UpdateMetricsResponse(absl::Duration response_time,
                                               int status_code,
                                               std::string_view resource_url) {
  if (metrics_ == nullptr) {
    return;
  }
  metrics_->UpdateMetricsResponse(response_time, status_code, resource_url);
}
// copybara:strip_end

}  // namespace milotic_tlbmc
