// 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 "BLINKY"
#include "blinky.h"

#include <mutex>

#include "modules/blinky/blinky.h"
#include "pw_async2/coro.h"
#include "pw_log/log.h"

namespace demo {

using ::pw::Allocator;
using ::pw::OkStatus;
using ::pw::Status;
using ::pw::async2::Coro;
using ::pw::async2::CoroContext;
using ::pw::async2::Dispatcher;
using ::pw::async2::TimeProvider;
using ::pw::chrono::SystemClock;
using ::pw::digital_io::DigitalInOut;
using ::pw::digital_io::State;

namespace {

bool IsOn(DigitalInOut& io) {
  auto result = io.GetState();
  if (!result.ok()) {
    return false;
  }
  return *result == State::kActive;
}

void TurnOn(DigitalInOut& io) { io.SetState(State::kActive).IgnoreError(); }

void TurnOff(DigitalInOut& io) { io.SetState(State::kInactive).IgnoreError(); }

void ToggleIo(DigitalInOut& io) {
  io.SetState(IsOn(io) ? State::kInactive : State::kActive).IgnoreError();
}

}  // namespace

Coro<Status> Blinky::BlinkLoop(CoroContext&,
                               uint32_t blink_count,
                               pw::chrono::SystemClock::duration interval) {
  for (uint32_t blinked = 0; blinked < blink_count || blink_count == 0;
       ++blinked) {
    {
      PW_LOG_INFO("LED blinking: OFF");
      std::lock_guard lock(lock_);
      TurnOff(*monochrome_led_);
    }
    co_await time_->WaitFor(interval);
    {
      PW_LOG_INFO("LED blinking: ON");
      std::lock_guard lock(lock_);
      TurnOn(*monochrome_led_);
    }
    co_await time_->WaitFor(interval);
  }
  {
    std::lock_guard lock(lock_);
    TurnOff(*monochrome_led_);
  }
  PW_LOG_INFO("Stopped blinking");
  co_return OkStatus();
}

Blinky::Blinky()
    : blink_task_(Coro<Status>::Empty(), [](Status) {
        PW_LOG_ERROR("Failed to allocate blink loop coroutine.");
      }) {}

void Blinky::Init(Dispatcher& dispatcher,
                  TimeProvider<SystemClock>& time,
                  Allocator& allocator,
                  pw::digital_io::DigitalInOut& monochrome_led) {
  dispatcher_ = &dispatcher;
  time_ = &time;
  allocator_ = &allocator;

  std::lock_guard lock(lock_);
  monochrome_led_ = &monochrome_led;
  monochrome_led_->Enable().IgnoreError();
  TurnOff(*monochrome_led_);
}

Blinky::~Blinky() { blink_task_.Deregister(); }

void Blinky::Toggle() {
  blink_task_.Deregister();
  PW_LOG_INFO("Toggling LED");
  std::lock_guard lock(lock_);
  ToggleIo(*monochrome_led_);
}

void Blinky::SetLed(bool on) {
  blink_task_.Deregister();
  std::lock_guard lock(lock_);
  if (on) {
    PW_LOG_INFO("Setting LED on");
    TurnOn(*monochrome_led_);
  } else {
    PW_LOG_INFO("Setting LED off");
    TurnOff(*monochrome_led_);
  }
}

pw::Status Blinky::Blink(uint32_t blink_count, uint32_t interval_ms) {
  if (blink_count == 0) {
    PW_LOG_INFO("Blinking forever at a %ums interval", interval_ms);
  } else {
    PW_LOG_INFO(
        "Blinking %u times at a %ums interval", blink_count, interval_ms);
  }

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

  blink_task_.Deregister();
  CoroContext coro_cx(*allocator_);
  blink_task_.SetCoro(BlinkLoop(coro_cx, blink_count, interval));
  dispatcher_->Post(blink_task_);
  return OkStatus();
}

bool Blinky::IsIdle() const {
  std::lock_guard lock(lock_);
  return !blink_task_.IsRegistered();
}

}  // namespace demo
