#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 {

bool SharedMemoryServer::IsInitialized() {
  return SegmentManager::IsInitialized();
}

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::SetUpInstanceForUnitTestReadOnly() {
  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}),
      is_segment_manager_dummy_(segment_manager == nullptr),
      segment_manager_(segment_manager == nullptr
                           ? std::make_unique<SegmentManagerDummy>()
                           : std::move(segment_manager)),
      metrics_(segment_manager_ == nullptr
                   ? nullptr
                   : segment_manager_->GetOrCreateMetrics()) {
  if (is_segment_manager_dummy_) {
    LOG(ERROR) << "SharedMemoryServer segment_manager is nullptr. This should "
                  "never happen in server side. Check the initialization log. "
                  "A fake segment manager has been used.";
  }
}

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);
}

void SharedMemoryServer::UpdateMetricsRps(absl::Duration time_delta) {
  if (metrics_ == nullptr) {
    return;
  }
  metrics_->UpdateMetricsRps(time_delta);
}
// copybara:strip_end

}  // namespace milotic_tlbmc
