#include "TBeamLogger.h"

namespace tbeam
{

  bool TBeamLogger::begin(Print &serial, TBeamStorage *storage, const LoggerConfig &config)
  {
    serial_ = &serial;
    storage_ = storage;
    config_ = config;
    lastFlushMs_ = millis();
    return true;
  }

  void TBeamLogger::update()
  {
    if (!config_.autoFlush || !storage_)
    {
      return;
    }
    const uint32_t now = millis();
    if ((uint32_t)(now - lastFlushMs_) >= config_.flushIntervalMs)
    {
      storage_->flush();
      lastFlushMs_ = now;
    }
  }

  bool TBeamLogger::openLog(const char *path)
  {
    return storage_ && storage_->openLog(path);
  }

  bool TBeamLogger::openUniqueLog(const char *prefix, const char *extension)
  {
    if (!storage_)
    {
      return false;
    }
    char path[128];
    if (!storage_->makeUniqueLogPath(prefix, extension, path, sizeof(path)))
    {
      return false;
    }
    return storage_->openLog(path);
  }

  const char *TBeamLogger::currentLogPath() const
  {
    return storage_ ? storage_->currentLogPath() : "";
  }

  bool TBeamLogger::storageReady() const
  {
    return storage_ && storage_->ready() && storage_->isLogOpen();
  }

  void TBeamLogger::flush()
  {
    if (storage_)
    {
      storage_->flush();
    }
    if (serial_)
    {
      serial_->flush();
    }
  }

  void TBeamLogger::closeLog()
  {
    if (storage_)
    {
      storage_->closeLog();
    }
  }

  size_t TBeamLogger::write(uint8_t value)
  {
    return write(&value, 1);
  }

  size_t TBeamLogger::write(const uint8_t *buffer, size_t size)
  {
    size_t serialWrote = 0;
    size_t storageWrote = 0;
    if (config_.echoSerial && serial_)
    {
      serialWrote = serial_->write(buffer, size);
    }
    if (config_.echoStorage && storage_ && storage_->isLogOpen())
    {
      storageWrote = storage_->write(buffer, size);
    }
    return storageWrote > 0 ? storageWrote : serialWrote;
  }

} // namespace tbeam
