// Copyright 2024 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#define PW_LOG_MODULE_NAME "MORSE"
#define PW_LOG_LOG_LEVEL PW_LOG_LEVEL_INFO

#include "modules/morse_code/encoder.h"

#include <cctype>
#include <mutex>

#include "pw_function/function.h"
#include "pw_log/log.h"

namespace sense {

Encoder::~Encoder() { encode_task_.Deregister(); }

void Encoder::Init(pw::async2::Dispatcher& dispatcher,
                   pw::async2::TimeProvider<pw::chrono::SystemClock>& time,
                   pw::Allocator& allocator,
                   OutputFunction&& output) {
  dispatcher_ = &dispatcher;
  time_ = &time;
  allocator_ = &allocator;
  output_ = std::move(output);
}

pw::Status Encoder::Encode(std::string_view msg,
                           uint32_t repeat,
                           uint32_t interval_ms) {
  if (repeat == 0) {
    PW_LOG_INFO("Encoding message forever at a %ums interval", interval_ms);
    repeat = std::numeric_limits<uint32_t>::max();
  } else {
    PW_LOG_INFO(
        "Encoding message %u times at a %ums interval", repeat, interval_ms);
  }

  pw::chrono::SystemClock::duration interval =
      pw::chrono::SystemClock::for_at_least(
          std::chrono::milliseconds(interval_ms));

  encode_task_.Deregister();
  pw::async2::CoroContext coro_cx(*allocator_);
  pw::async2::Coro<pw::Status> coro =
      EncodeLoop(coro_cx, msg, repeat, interval);
  if (!coro.IsValid()) {
    PW_LOG_ERROR("Failed to allocate morse encoder coroutine.");
    return pw::Status::ResourceExhausted();
  }
  encode_task_.SetCoro(std::move(coro));
  dispatcher_->Post(encode_task_);
  return pw::OkStatus();
}

bool Encoder::IsIdle() const { return !encode_task_.IsRegistered(); }

pw::async2::Coro<pw::Status> Encoder::EncodeLoop(
    pw::async2::CoroContext&,
    pw::InlineString<kMaxMsgLen> msg,
    uint32_t repeat,
    pw::chrono::SystemClock::duration interval) {
  if (msg.size() == 0 || msg[0] == '\0') {
    co_return pw::OkStatus();
  }
  for (; repeat > 0; --repeat) {
    for (uint32_t msg_offset = 0; msg_offset < msg.size(); ++msg_offset) {
      char c = msg[msg_offset];
      if (c == '\0') {
        break;
      }

      if (isspace(c)) {
        // Merge consecutive whitespace characters.
        bool prev_was_space = msg_offset != 0 && isspace(msg[msg_offset - 1]);
        if (prev_was_space) {
          continue;
        }

        // Words are separated by 7 dits worth of blanks.
        // The previous symbol ended with 3 blanks, so add 4 more.
        co_await time_->WaitFor(interval * 4);
        continue;
      }

      // Encode the character.
      const auto& encoding = ForChar(c);
      uint32_t remaining_bits = encoding.bits;
      bool is_on = false;
      for (uint8_t num_bits = encoding.num_bits; num_bits > 0; --num_bits) {
        bool on = (remaining_bits % 2) != 0;
        remaining_bits >>= 1;
        if (on != is_on) {
          Output output;
          output.on_ = on;
          output.message_finished_ = false;
          output_(output);
          is_on = on;
        }
        co_await time_->WaitFor(interval);
      }
    }
    Output output;
    output.on_ = false;
    output.message_finished_ = true;
    output_(output);
  }
  co_return pw::OkStatus();
}

}  // namespace sense
