// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

// THIS FILE WAS AUTO-GENERATED BY ./ntcore/generate_topics.py. DO NOT MODIFY

#include "wpi/nt/ntcore_cpp_types.hpp"

#include "Handle.hpp"
#include "InstanceImpl.hpp"

namespace {
template <wpi::nt::ValidType T>
struct ValuesType {
  using Vector =
      std::vector<typename wpi::nt::TypeInfo<std::remove_cvref_t<T>>::Value>;
};

template <>
struct ValuesType<bool> {
  using Vector = std::vector<int>;
};
}  // namespace

namespace wpi::nt {

template <ValidType T>
static inline bool Set(NT_Handle pubentry, typename TypeInfo<T>::View value,
                       int64_t time) {
  if (auto ii = InstanceImpl::Get(Handle{pubentry}.GetInst())) {
    return ii->localStorage.SetEntryValue(
        pubentry, MakeValue<T>(value, time == 0 ? Now() : time));
  } else {
    return {};
  }
}

template <ValidType T>
static inline bool SetDefault(NT_Handle pubentry,
                              typename TypeInfo<T>::View defaultValue) {
  if (auto ii = InstanceImpl::Get(Handle{pubentry}.GetInst())) {
    return ii->localStorage.SetDefaultEntryValue(pubentry,
                                                 MakeValue<T>(defaultValue, 1));
  } else {
    return {};
  }
}

template <ValidType T>
static inline Timestamped<typename TypeInfo<T>::Value> GetAtomic(
    NT_Handle subentry, typename TypeInfo<T>::View defaultValue) {
  if (auto ii = InstanceImpl::Get(Handle{subentry}.GetInst())) {
    return ii->localStorage.GetAtomic<T>(subentry, defaultValue);
  } else {
    return {};
  }
}

template <ValidType T>
inline Timestamped<typename TypeInfo<T>::SmallRet> GetAtomic(
    NT_Handle subentry,
    wpi::util::SmallVectorImpl<typename TypeInfo<T>::SmallElem>& buf,
    typename TypeInfo<T>::View defaultValue) {
  if (auto ii = InstanceImpl::Get(Handle{subentry}.GetInst())) {
    return ii->localStorage.GetAtomic<T>(subentry, buf, defaultValue);
  } else {
    return {};
  }
}

template <typename T>
static inline std::vector<Timestamped<typename TypeInfo<T>::Value>> ReadQueue(
    NT_Handle subentry) {
  if (auto ii = InstanceImpl::Get(Handle{subentry}.GetInst())) {
    return ii->localStorage.ReadQueue<T>(subentry);
  } else {
    return {};
  }
}

template <typename T>
static inline typename ValuesType<T>::Vector ReadQueueValues(
    NT_Handle subentry) {
  typename ValuesType<T>::Vector rv;
  auto arr = ReadQueue<T>(subentry);
  rv.reserve(arr.size());
  for (auto&& elem : arr) {
    rv.emplace_back(std::move(elem.value));
  }
  return rv;
}
{% for t in types %}
bool Set{{ t.TypeName }}(NT_Handle pubentry, {{ t.cpp.ParamType }} value, int64_t time) {
  return Set<{{ t.cpp.TemplateType }}>(pubentry, value, time);
}

bool SetDefault{{ t.TypeName }}(NT_Handle pubentry, {{ t.cpp.ParamType }} defaultValue) {
  return SetDefault<{{ t.cpp.TemplateType }}>(pubentry, defaultValue);
}

{{ t.cpp.ValueType }} Get{{ t.TypeName }}(NT_Handle subentry, {{ t.cpp.ParamType }} defaultValue) {
  return GetAtomic<{{ t.cpp.TemplateType }}>(subentry, defaultValue).value;
}

Timestamped{{ t.TypeName }} GetAtomic{{ t.TypeName }}(
    NT_Handle subentry, {{ t.cpp.ParamType }} defaultValue) {
  return GetAtomic<{{ t.cpp.TemplateType }}>(subentry, defaultValue);
}

std::vector<Timestamped{{ t.TypeName }}> ReadQueue{{ t.TypeName }}(NT_Handle subentry) {
  return ReadQueue<{{ t.cpp.TemplateType }}>(subentry);
}

std::vector<{% if t.cpp.ValueType == "bool" %}int{% else %}{{ t.cpp.ValueType }}{% endif %}> ReadQueueValues{{ t.TypeName }}(NT_Handle subentry) {
  return ReadQueueValues<{{ t.cpp.TemplateType }}>(subentry);
}
{% if t.cpp.SmallRetType and t.cpp.SmallElemType %}
{{ t.cpp.SmallRetType }} Get{{ t.TypeName }}(
    NT_Handle subentry,
    wpi::util::SmallVectorImpl<{{ t.cpp.SmallElemType }}>& buf,
    {{ t.cpp.ParamType }} defaultValue) {
  return GetAtomic<{{ t.cpp.TemplateType }}>(subentry, buf, defaultValue).value;
}

Timestamped{{ t.TypeName }}View GetAtomic{{ t.TypeName }}(
    NT_Handle subentry,
    wpi::util::SmallVectorImpl<{{ t.cpp.SmallElemType }}>& buf,
    {{ t.cpp.ParamType }} defaultValue) {
  return GetAtomic<{{ t.cpp.TemplateType }}>(subentry, buf, defaultValue);
}
{% endif %}
{% endfor %}
}  // namespace wpi::nt

