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

#include <cerrno>
#include <cstdint>
#include <filesystem>  // NOLINT
#include <fstream>
#include <limits>
#include <memory>
#include <new>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <utility>

#include "absl/base/no_destructor.h"
#include "absl/container/flat_hash_map.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "boost/interprocess/exceptions.hpp"  // NOLINT
#include "boost/interprocess/managed_shared_memory.hpp"  //NOLINT
#include "g3/macros.h"
#include "tlbmc/hal/shared_mem/metrics.h"
#include "tlbmc/hal/shared_mem/sensors.h"
#include "tlbmc/hal/shared_mem/server_interface.h"
#include "tlbmc/hal/shared_mem/static_shm_common.h"

namespace milotic_tlbmc {
namespace {
bool PathExists(const std::filesystem::path& path) {
  std::error_code ec;
  bool exists = std::filesystem::exists(path, ec);
  if (ec) {
    LOG(ERROR) << "Filesystem error while checking for " << path << ": "
               << ec.message();
    return false;
  }
  return exists;
}
}  // namespace

static std::unique_ptr<TlbmcSharedMemoryType> FindExistingSegment(
    const std::string& initialized_file_path, const std::string& shm_name) {
  if (!PathExists(initialized_file_path)) {
    return nullptr;
  }
  try {
    return std::make_unique<TlbmcSharedMemoryType>(
        boost::interprocess::open_only, shm_name.c_str());
  } catch (const boost::interprocess::interprocess_exception& e) {
    LOG(ERROR) << "Failed to open shared memory: " << e.what();
    return nullptr;
  }

  return nullptr;
}

static void LoadDataFromSegment(
    TlbmcSharedMemoryType& segment,
    absl::flat_hash_map<std::string, IpcSensor*>& sensors_idx) {
  for (auto it = segment.named_begin(); it != segment.named_end(); ++it) {
    const std::string_view name(it->name(), it->name_length());
    if (name.empty()) {
      continue;
    }
    if (name.starts_with("__")) {
      continue;
    }

    auto val = segment.find<IpcSensor>(it->name());
    if (val.first != nullptr) {
      sensors_idx[name] = val.first;
    }
  }
}

static std::unique_ptr<StaticSharedMemoryServer> LoadServer(
    const std::string& initialized_file_path, const std::string& shm_name) {
  auto shared_memory = FindExistingSegment(initialized_file_path, shm_name);
  if (shared_memory == nullptr) {
    return nullptr;
  }
  absl::flat_hash_map<std::string, IpcSensor*> sensors_idx;
  LoadDataFromSegment(*shared_memory, sensors_idx);
  return std::make_unique<StaticSharedMemoryServer>(
      std::move(shared_memory), std::move(sensors_idx),
      StaticSharedMemoryMetrics::GetInProcessMetrics());
}
/*   These values are approximate, with some headroom. Precise calculation would
 * require factoring in memory alignment, size of internal data structures, and
 * length of sensor names
 */
constexpr uint64_t kBytesPerSensor = 128;
constexpr uint64_t kMinObjectOverhead = 64;
constexpr uint64_t kConstantOverhead = 256;
static std::unique_ptr<TlbmcSharedMemoryType> CreateNewSegment(
    const std::string& shm_name, uint64_t sensor_count) {
  try {
    // Creates the segment.
    if (boost::interprocess::shared_memory_object::remove(shm_name.c_str())) {
      LOG(WARNING) << "Shared memory already existed without a initialization "
                      "file. Cleared previous segment ";
    }
    uint64_t size_to_reserve =
        (sensor_count * (sizeof(IpcSensor) + kBytesPerSensor)) +
        kConstantOverhead;

    return std::make_unique<TlbmcSharedMemoryType>(
        boost::interprocess::create_only, shm_name.c_str(), size_to_reserve);
  } catch (...) {
    return nullptr;
  }
  return nullptr;
}

class FallbackServer : public IpcServer {
 public:
  absl::StatusOr<std::pair<float, uint64_t>> ReadSensorValue(
      const std::string& /*sensor_name*/) override {
    return absl::UnavailableError(
        "Using fallback server due to error initializing shared memory");
  }
  // copybara:strip_begin(g3-shared-libs)
  void UpdateMetricsRequestCount(bool is_tlbmc_request) override {
    StaticSharedMemoryMetrics::GetInProcessMetrics()->UpdateMetricsRequestCount(
        is_tlbmc_request);
  }
  void UpdateMetricsResponse(absl::Duration response_time, int status_code,
                             std::string_view resource_url) override {
    StaticSharedMemoryMetrics::GetInProcessMetrics()->UpdateMetricsResponse(
        response_time, status_code, resource_url);
  }
  void UpdateMetricsRps(absl::Duration time_delta) override {
    StaticSharedMemoryMetrics::GetInProcessMetrics()->UpdateMetricsRps(
        time_delta);
  }
  // copybara:strip_end
};
class StaticSharedMemoryInitializer {
  static absl::Status CreateInitFile(const std::string& initialized_file_path) {
    std::filesystem::path const directory =
        std::filesystem::path(initialized_file_path).parent_path();
    if (!PathExists(directory)) {
      std::error_code ec;
      std::filesystem::create_directories(directory, ec);
      if (ec) {
        LOG(ERROR) << "Failed to create directory: " << directory << ": "
                   << ec.message();
        return absl::InternalError("Failed to create directory");
      }
    }
    errno = 0;
    std::ofstream file(std::string{initialized_file_path});
    if (!file.is_open()) {
      int const error_num = errno;
      auto error_message =
          absl::StrCat("Failed to open file at: ", initialized_file_path);
      if (error_num != 0) {
        return absl::ErrnoToStatus(error_num, error_message);
      }
      return absl::UnavailableError(error_message);
    }
    // An error can happen during write/flush but we don't rely on the contents
    // of the file so we can ignore the error here
    file << 1;
    file.flush();
    return absl::OkStatus();
  }
  static absl::Status Allocate(TlbmcSharedMemoryType& segment,
                               absl::Span<const std::string> shm_sensors) {
    segment.reserve_named_objects(shm_sensors.size());
    for (const auto& sensor_name : shm_sensors) {
      if (segment.construct<IpcSensor>(sensor_name.c_str(), std::nothrow)() ==
          nullptr) {
        return absl::UnknownError("Cannot allocate sensor");
      }
    }
    return absl::OkStatus();
  }

 public:
  static absl::Status Initialize(
      const std::string& initialized_file_path, const std::string& shm_name,
      const absl::Span<const std::string> shm_sensors) {
    if (FindExistingSegment(initialized_file_path, shm_name) != nullptr) {
      return absl::OkStatus();
    }
    auto new_segment = CreateNewSegment(shm_name, shm_sensors.size());
    if (new_segment == nullptr) {
      return absl::InternalError("Failed to create new shared memory");
    }
    ECCLESIA_RETURN_IF_ERROR(Allocate(*new_segment, shm_sensors));
    auto status = CreateInitFile(initialized_file_path);
    if (!status.ok()) {
      LOG(ERROR) << "Failed to create init file" << status;
      return status;
    }
    return absl::OkStatus();
  }

  static void TearDownForTesting(const std::string& initialized_file_path) {
    std::error_code ec;
    std::filesystem::remove(initialized_file_path, ec);
    if (ec) {
      LOG(ERROR) << "Error calling remove for path '" << initialized_file_path
                 << "': " << ec.message();
    }
  }
};
absl::Status StaticSharedMemoryServer::InitializeSharedMemoryForUnitTest(
    absl::Span<const std::string> shm_sensors) {
  StaticSharedMemoryInitializer::TearDownForTesting(
      "/tmp/tlbmc/static_shm_initialized");
  return InitializeSharedMemory("/tmp/tlbmc/static_shm_initialized",
                                kStaticShmName, shm_sensors);
}
void StaticSharedMemoryServer::SetupInstanceForUnitTest() {
  GetInstance("/tmp/tlbmc/static_shm_initialized", kStaticShmName, true);
}

absl::Status StaticSharedMemoryServer::InitializeSharedMemory(
    absl::Span<const std::string> shm_sensors) {
  return InitializeSharedMemory(kStaticShmInitializedFile, kStaticShmName,
                                shm_sensors);
}
absl::Status StaticSharedMemoryServer::InitializeSharedMemory(
    const std::string& initialized_file_path, const std::string& shm_name,
    absl::Span<const std::string> shm_sensors) {
  return StaticSharedMemoryInitializer::Initialize(initialized_file_path,
                                                   shm_name, shm_sensors);
}
IpcServer& StaticSharedMemoryServer::GetInstance() {
  return GetInstance(kStaticShmInitializedFile, kStaticShmName);
}
std::unique_ptr<IpcServer> StaticSharedMemoryServer::PerformServerInit(
    const std::string& initialized_file_path, const std::string& shm_name) {
  std::unique_ptr<StaticSharedMemoryServer> server =
      LoadServer(initialized_file_path, shm_name);
  if (server == nullptr) {
    LOG(ERROR) << "Failed to initialize shared memory server , falling "
                  "back to dummy ";
    return std::make_unique<FallbackServer>();
  }
  return server;
}
IpcServer& StaticSharedMemoryServer::GetInstance(
    const std::string& initialized_file_path, const std::string& shm_name,
    bool force_reset_for_testing) {
  static absl::NoDestructor instance(
      (PerformServerInit(initialized_file_path, shm_name)));
  if (force_reset_for_testing) {
    *instance = PerformServerInit(initialized_file_path, shm_name);
  }
  return **instance;
}

absl::StatusOr<std::pair<float, uint64_t>>
StaticSharedMemoryServer::ReadSensorValue(const std::string& sensor_name) {
  auto sensor_entry = name_to_sensor_.find(sensor_name);
  if (sensor_entry == name_to_sensor_.end()) {
    return absl::UnavailableError("Requested sensor does not exist");
  }
  std::pair<float, uint64_t> value = sensor_entry->second->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 StaticSharedMemoryServer::UpdateMetricsRequestCount(
    bool is_tlbmc_request) {
  if (metrics_ == nullptr) {
    return;
  }
  metrics_->UpdateMetricsRequestCount(is_tlbmc_request);
}

void StaticSharedMemoryServer::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 StaticSharedMemoryServer::UpdateMetricsRps(absl::Duration time_delta) {
  if (metrics_ == nullptr) {
    return;
  }
  metrics_->UpdateMetricsRps(time_delta);
}
// copybara:strip_end
StaticSharedMemoryServer::StaticSharedMemoryServer(
    std::unique_ptr<TlbmcSharedMemoryType> memory,
    absl::flat_hash_map<std::string, IpcSensor*> name_to_sensor,
    TlbmcMetrics* metrics)
    : memory_(std::move(memory)),
      name_to_sensor_(std::move(name_to_sensor)),
      metrics_(metrics) {}

}  // namespace milotic_tlbmc
