#include "one_wire.h"

namespace esphome::one_wire {

static const char *const TAG = "one_wire";

const std::string &OneWireDevice::get_address_name() {
  if (this->address_name_.empty()) {
    char hex_buf[19];  // "0x" + 16 hex chars + null
    this->address_name_ = format_hex_prefixed_to(hex_buf, this->address_);
  }
  return this->address_name_;
}

void OneWireDevice::set_address(uint64_t address) {
  this->address_ = address;
  this->address_name_.clear();
}

bool OneWireDevice::send_command_(uint8_t cmd) {
  if (!this->bus_->select(this->address_))
    return false;
  this->bus_->write8(cmd);
  return true;
}

bool OneWireDevice::check_address_or_index_() {
  if (this->address_ != 0)
    return true;
  auto devices = this->bus_->get_devices();

  if (this->index_ != INDEX_NOT_SET) {
    if (this->index_ >= devices.size()) {
      ESP_LOGE(TAG, "Index %d out of range, only %d devices found", this->index_, devices.size());
      return false;
    }
    this->address_ = devices[this->index_];
    return true;
  }

  if (devices.empty()) {
    ESP_LOGE(TAG, "No devices, can't auto-select address");
    return false;
  }
  if (devices.size() > 1) {
    ESP_LOGE(TAG, "More than one device, can't auto-select address");
    return false;
  }
  this->address_ = devices[0];
  return true;
}

}  // namespace esphome::one_wire
