// 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.

#include "modules/blinky/blinky.h"

#include "modules/led/monochrome_led_fake.h"
#include "modules/led/polychrome_led_fake.h"
#include "pw_allocator/testing.h"
#include "pw_async2/dispatcher.h"
#include "pw_async2/simulated_time_provider.h"
#include "pw_unit_test/framework.h"

namespace sense {

using AllocatorForTest = ::pw::allocator::test::AllocatorForTest<512>;
using ::pw::async2::Dispatcher;
using ::pw::async2::SimulatedTimeProvider;
using ::pw::chrono::SystemClock;

// Test fixtures.

class BlinkyTest : public ::testing::Test {
 protected:
  using Event = ::sense::MonochromeLedFake::Event;
  using State = ::sense::MonochromeLedFake::State;

  static constexpr uint32_t kIntervalMs = 10;
  static constexpr pw::chrono::SystemClock::duration kInterval =
      pw::chrono::SystemClock::for_at_least(
          std::chrono::milliseconds(kIntervalMs));

  BlinkyTest() : monochrome_led_(time_) {
    blinky_.Init(
        dispatcher_, time_, allocator_, monochrome_led_, polychrome_led_);
  }

  pw::InlineDeque<Event>::iterator FirstActive() {
    pw::InlineDeque<Event>& events = monochrome_led_.events();
    pw::InlineDeque<Event>::iterator event = events.begin();
    while (event != events.end()) {
      if (event->state == State::kActive) {
        break;
      }
      ++event;
    }
    return event;
  }

  uint32_t ToMs(pw::chrono::SystemClock::duration interval) {
    return std::chrono::duration_cast<std::chrono::milliseconds>(interval)
        .count();
  }

  AllocatorForTest allocator_;
  Dispatcher dispatcher_;
  SimulatedTimeProvider<SystemClock> time_;
  MonochromeLedFake monochrome_led_;
  PolychromeLedFake polychrome_led_;
  Blinky blinky_;
};

// Unit tests.

TEST_F(BlinkyTest, Toggle) {
  auto start = time_.now();
  blinky_.Toggle();
  time_.AdvanceTime(kInterval * 1);
  blinky_.Toggle();
  time_.AdvanceTime(kInterval * 2);
  blinky_.Toggle();
  time_.AdvanceTime(kInterval * 3);
  blinky_.Toggle();

  auto event = FirstActive();
  ASSERT_NE(event, monochrome_led_.events().end());
  EXPECT_EQ(event->state, State::kActive);
  EXPECT_GE(ToMs(event->timestamp - start), kIntervalMs * 0);
  start = event->timestamp;

  ASSERT_NE(++event, monochrome_led_.events().end());
  EXPECT_EQ(event->state, State::kInactive);
  EXPECT_GE(ToMs(event->timestamp - start), kIntervalMs * 1);
  start = event->timestamp;

  ASSERT_NE(++event, monochrome_led_.events().end());
  EXPECT_EQ(event->state, State::kActive);
  EXPECT_GE(ToMs(event->timestamp - start), kIntervalMs * 2);
  start = event->timestamp;

  ASSERT_NE(++event, monochrome_led_.events().end());
  EXPECT_EQ(event->state, State::kInactive);
  EXPECT_GE(ToMs(event->timestamp - start), kIntervalMs * 3);
}

TEST_F(BlinkyTest, Blink) {
  auto start = time_.now();
  EXPECT_EQ(blinky_.Blink(1, kIntervalMs), pw::OkStatus());
  while (!blinky_.IsIdle()) {
    dispatcher_.RunUntilStalled().IgnorePoll();
    time_.AdvanceUntilNextExpiration();
  }

  auto event = FirstActive();
  ASSERT_NE(event, monochrome_led_.events().end());
  EXPECT_EQ(event->state, State::kActive);
  EXPECT_GE(ToMs(event->timestamp - start), kIntervalMs);
  start = event->timestamp;

  ASSERT_NE(++event, monochrome_led_.events().end());
  EXPECT_EQ(event->state, State::kInactive);
  EXPECT_GE(ToMs(event->timestamp - start), kIntervalMs);
}

TEST_F(BlinkyTest, BlinkMany) {
  auto start = time_.now();
  EXPECT_EQ(blinky_.Blink(100, kIntervalMs), pw::OkStatus());
  while (!blinky_.IsIdle()) {
    dispatcher_.RunUntilStalled().IgnorePoll();
    time_.AdvanceUntilNextExpiration();
  }

  // Every "on" and "off" is recorded.
  EXPECT_GE(monochrome_led_.events().size(), 200);
  EXPECT_GE(ToMs(time_.now() - start), kIntervalMs * 200);
}

TEST_F(BlinkyTest, BlinkSlow) {
  auto start = time_.now();
  EXPECT_EQ(blinky_.Blink(1, kIntervalMs * 32), pw::OkStatus());
  while (!blinky_.IsIdle()) {
    dispatcher_.RunUntilStalled().IgnorePoll();
    time_.AdvanceUntilNextExpiration();
  }

  auto event = FirstActive();
  ASSERT_NE(event, monochrome_led_.events().end());
  EXPECT_EQ(event->state, State::kActive);
  EXPECT_GE(ToMs(event->timestamp - start), kIntervalMs * 32);
  start = event->timestamp;

  ASSERT_NE(++event, monochrome_led_.events().end());
  EXPECT_EQ(event->state, State::kInactive);
  EXPECT_GE(ToMs(event->timestamp - start), kIntervalMs * 32);
}

}  // namespace sense
