// 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 "BUTTONS"

#include "modules/buttons/manager.h"

#include "pw_log/log.h"
#include "pw_status/try.h"

using pw::chrono::SystemClock;
using pw::digital_io::State;

namespace sense {
State Debouncer::UpdateState(SystemClock::time_point now, State state) {
  if (state != last_input_) {
    last_update_ = now;
    last_input_ = state;
  } else if (now - last_update_ >= kDebounceInterval) {
    output_ = state;
  }

  return output_;
}

EdgeDetector::StateChange EdgeDetector::UpdateState(State state) {
  auto prev_state = current_state_;
  current_state_ = state;

  if (prev_state == State::kInactive && current_state_ == State::kActive) {
    return StateChange::kActivate;
  }
  if (prev_state == State::kActive && current_state_ == State::kInactive) {
    return StateChange::kDeactivate;
  }
  return StateChange::kNone;
}

pw::Result<EdgeDetector::StateChange> Button::Sample(
    SystemClock::time_point now) {
  PW_TRY_ASSIGN(auto raw_state, io_.GetState());
  auto deboucned_state = debouncer_.UpdateState(now, raw_state);
  return edge_detector_.UpdateState(deboucned_state);
}

ButtonManager::ButtonManager(pw::digital_io::DigitalIn& button_a,
                             pw::digital_io::DigitalIn& button_b,
                             pw::digital_io::DigitalIn& button_x,
                             pw::digital_io::DigitalIn& button_y)
    : buttons_{
          Button(button_a),
          Button(button_b),
          Button(button_x),
          Button(button_y),
      }, sample_task_(pw::async2::Coro<pw::Status>::Empty(), [](pw::Status) {
        PW_LOG_ERROR("Failed to allocate blink loop coroutine.");
      }) {}

ButtonManager::~ButtonManager() { Stop(); }

void ButtonManager::Init(pw::async2::Dispatcher& dispatcher,
                         pw::async2::TimeProvider<SystemClock>& time,
                         pw::Allocator& allocator,
                         PubSub& pub_sub) {
  pub_sub_ = &pub_sub;
  dispatcher_ = &dispatcher;
  time_ = &time;

  pw::async2::CoroContext coro_cx(allocator);
  sample_task_.SetCoro(SampleLoop(coro_cx));

  // Start the periodic sampling.
  Start();
}

pw::async2::Coro<pw::Status> ButtonManager::SampleLoop(
    pw::async2::CoroContext) {
  while (true) {
    auto now = time_->now();
    if (const auto status = SampleButtons(now); !status.ok()) {
      PW_LOG_ERROR("Failed to sample buttons: %s", status.str());
    }
    co_await time_->WaitUntil(now + kSampleInterval);
  }
}

template <typename ButtonEvent>
pw::Status ButtonManager::SampleButton(Button& button,
                                       SystemClock::time_point now) {
  PW_TRY_ASSIGN(auto state_change, button.Sample(now));
  if (state_change == EdgeDetector::StateChange::kActivate) {
    std::ignore = pub_sub_->Publish(ButtonEvent(true));
  } else if (state_change == EdgeDetector::StateChange::kDeactivate) {
    std::ignore = pub_sub_->Publish(ButtonEvent(false));
  }
  return pw::OkStatus();
}

pw::Status ButtonManager::SampleButtons(SystemClock::time_point now) {
  PW_TRY(SampleButton<sense::ButtonA>(buttons_[0], now));
  PW_TRY(SampleButton<sense::ButtonB>(buttons_[1], now));
  PW_TRY(SampleButton<sense::ButtonX>(buttons_[2], now));
  PW_TRY(SampleButton<sense::ButtonY>(buttons_[3], now));
  return pw::OkStatus();
}

}  // namespace sense
