// 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.
#pragma once

#include <chrono>

#include "modules/pubsub/pubsub_events.h"
#include "pw_allocator/allocator.h"
#include "pw_assert/check.h"
#include "pw_async2/coro.h"
#include "pw_async2/coro_or_else_task.h"
#include "pw_async2/dispatcher.h"
#include "pw_async2/time_provider.h"
#include "pw_chrono/system_clock.h"
#include "pw_digital_io/digital_io.h"
#include "pw_status/status.h"

namespace sense {
class Debouncer final {
 public:
  constexpr static pw::chrono::SystemClock::duration kDebounceInterval =
      std::chrono::milliseconds(30);

  Debouncer(pw::digital_io::State initial_state)
      : last_input_(initial_state) {};
  pw::digital_io::State UpdateState(pw::chrono::SystemClock::time_point now,
                                    pw::digital_io::State state);

 private:
  pw::chrono::SystemClock::time_point last_update_ =
      pw::chrono::SystemClock::time_point();
  pw::digital_io::State last_input_ = pw::digital_io::State::kInactive;
  pw::digital_io::State output_ = pw::digital_io::State::kInactive;
};

class EdgeDetector final {
 public:
  EdgeDetector(pw::digital_io::State initial_state)
      : current_state_(initial_state) {};

  enum StateChange {
    kNone,
    kActivate,
    kDeactivate,
  };

  StateChange UpdateState(pw::digital_io::State state);

 private:
  pw::digital_io::State current_state_;
};

class Button {
 public:
  Button(pw::digital_io::DigitalIn& io) : io_(io) {
    PW_CHECK_OK(io_.Enable());
  };

  pw::Result<EdgeDetector::StateChange> Sample(
      pw::chrono::SystemClock::time_point now);

 private:
  pw::digital_io::DigitalIn& io_;
  Debouncer debouncer_ = Debouncer(pw::digital_io::State::kInactive);
  EdgeDetector edge_detector_ = EdgeDetector(pw::digital_io::State::kInactive);
};

/// DOCME
class ButtonManager final {
 public:
  constexpr static pw::chrono::SystemClock::duration kSampleInterval =
      std::chrono::milliseconds(10);

  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);
  ~ButtonManager();

  void Init(pw::async2::Dispatcher& dispatcher,
            pw::async2::TimeProvider<pw::chrono::SystemClock>& time,
            pw::Allocator& allocator,
            PubSub& pub_sub);

  void Start() {
    if (!sample_task_.IsRegistered()) {
      dispatcher_->Post(sample_task_);
    }
  }

  void Stop() { sample_task_.Deregister(); }

 private:
  Button buttons_[4];

  pw::async2::Coro<pw::Status> SampleLoop(pw::async2::CoroContext cx);

  template <typename ButtonEvent>
  pw::Status SampleButton(Button& button, pw::chrono::SystemClock::time_point);
  pw::Status SampleButtons(pw::chrono::SystemClock::time_point);

  PubSub* pub_sub_ = nullptr;
  pw::async2::Dispatcher* dispatcher_ = nullptr;
  pw::async2::TimeProvider<pw::chrono::SystemClock>* time_;
  pw::async2::CoroOrElseTask sample_task_;
};
}  // namespace sense
