// 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/morse_code/encoder.h"

#include <chrono>
#include <cstdint>

#include "modules/led/monochrome_led_fake.h"
#include "pw_allocator/testing.h"
#include "pw_async2/dispatcher_for_test.h"
#include "pw_async2/simulated_time_provider.h"
#include "pw_containers/vector.h"
#include "pw_status/status.h"
#include "pw_unit_test/framework.h"

namespace sense {

using AllocatorForTest = ::pw::allocator::test::AllocatorForTest<1024>;

// Test fixtures.

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

  static constexpr uint32_t kIntervalMs = 10;

  auto LedOutput() {
    return [this](const Encoder::Output& output) {
      FakeLedOutput(output.on(), output.message_finished());
    };
  }

  MorseCodeEncoderTest() : led_(time_) {
    encoder_.Init(dispatcher_, time_, allocator_, LedOutput());
  }

  void Expect(std::string_view msg) {
    EXPECT_EQ(end_of_pattern_count_, expected_messages_);

    auto& events = led_.events();
    auto event = events.begin();

    // Skip until the first "turn on" event is seen, and use it as the starting
    // point.
    while (true) {
      if (event == events.end()) {
        EXPECT_TRUE(msg.empty());
        return;
      }
      if (event->state == State::kActive) {
        break;
      }
      ++event;
    }
    auto start = event->timestamp;
    ++event;

    while (!msg.empty()) {
      size_t off_intervals;
      size_t offset;
      if (msg.substr(1, 2) == "  ") {
        // Word break
        off_intervals = 7;
        offset = 3;

      } else if (msg.substr(1, 1) == " ") {
        // Letter break
        off_intervals = 3;
        offset = 2;

      } else {
        // Symbol break
        off_intervals = 1;
        offset = 1;
      }

      // Check that the LED turns off after the roght amount of time, implying
      /// it was on.
      ASSERT_NE(event, events.end());
      EXPECT_EQ(event->state, State::kInactive);
      if (msg[0] == '.') {
        EXPECT_GE(ToMs(event->timestamp - start), interval_ms_);
      } else if (msg[0] == '-') {
        EXPECT_GE(ToMs(event->timestamp - start), interval_ms_ * 3);
      } else {
        FAIL();
      }
      start = event->timestamp;
      ++event;

      msg = msg.substr(offset);
      if (msg.empty()) {
        break;
      }

      // Check that the LED turns on after the right amount of time, implying
      /// it was off.
      ASSERT_NE(event, events.end());
      EXPECT_EQ(event->state, State::kActive);
      EXPECT_GE(ToMs(event->timestamp - start), interval_ms_ * off_intervals);
      start = event->timestamp;
      ++event;
    }
    events.clear();
  }

  uint32_t ToMs(pw::chrono::SystemClock::duration interval) {
    return std::chrono::duration_cast<std::chrono::milliseconds>(interval)
        .count();
  }
  /// Waits until the given encoder is idle.
  void SleepUntilDone() {
    while (!encoder_.IsIdle()) {
      dispatcher_.RunUntilStalled();
      time_.AdvanceUntilNextExpiration();
    }
  }

  Encoder encoder_;
  uint32_t interval_ms_ = kIntervalMs;

  // Number of messages encoded before the next Expect() call.
  int expected_messages_ = 1;

 private:
  void FakeLedOutput(bool turn_on, bool pattern_finished) {
    if (turn_on) {
      led_.TurnOn();
    } else {
      led_.TurnOff();
    }

    // Track how many times the last bit in the pattern is seen.
    if (pattern_finished) {
      end_of_pattern_count_ += 1;
      EXPECT_LE(end_of_pattern_count_, expected_messages_);
    } else if (expected_messages_ == 0u) {
      EXPECT_EQ(end_of_pattern_count_, expected_messages_);
    } else {
      EXPECT_LT(end_of_pattern_count_, expected_messages_);
    }
  }

  pw::async2::DispatcherForTest dispatcher_;
  pw::async2::SimulatedTimeProvider<pw::chrono::SystemClock> time_;
  AllocatorForTest allocator_;
  MonochromeLedFake led_;
  int end_of_pattern_count_ = 0;
};

// Unit tests.

TEST_F(MorseCodeEncoderTest, EncodeEmpty) {
  expected_messages_ = 0;
  EXPECT_EQ(encoder_.Encode("", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  Expect("");
}

TEST_F(MorseCodeEncoderTest, EncodeOneLetter) {
  EXPECT_EQ(encoder_.Encode("E", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  Expect(".");
}

TEST_F(MorseCodeEncoderTest, EncodeOneWord) {
  EXPECT_EQ(encoder_.Encode("PARIS", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  Expect(".--. .- .-. .. ...");
}

TEST_F(MorseCodeEncoderTest, EncodeHelloWorld) {
  EXPECT_EQ(encoder_.Encode("hello world", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();

  Expect(".... . .-.. .-.. ---  .-- --- .-. .-.. -..");
}

// TODO(b/352327457): Without simulated time, this test is too slow to run every
// case on device.
#if defined(AM_MORSE_CODE_ENCODER_TEST_FULL) && AM_MORSE_CODE_ENCODER_TEST_FULL

TEST_F(MorseCodeEncoderTest, EncodeRepeated) {
  expected_messages_ = 2;
  EXPECT_EQ(encoder_.Encode("hello", 2, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  Expect(".... . .-.. .-.. ---  .... . .-.. .-.. ---");
}

TEST_F(MorseCodeEncoderTest, EncodeSlow) {
  interval_ms_ = 25;
  EXPECT_EQ(encoder_.Encode("hello", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  Expect(".... . .-.. .-.. ---");
}

TEST_F(MorseCodeEncoderTest, EncodeConsecutiveWhitespace) {
  EXPECT_EQ(encoder_.Encode("hello    world", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  Expect(".... . .-.. .-.. ---  .-- --- .-. .-.. -..");
}

TEST_F(MorseCodeEncoderTest, EncodeInvalidChars) {
  char s[2];
  s[1] = 0;

  expected_messages_ = 0;

  for (char c = 127; c != 0; --c) {
    if (isspace(c) || isalnum(c) || c == '?' || c == '@') {
      continue;
    }
    s[0] = c;
    expected_messages_ += 1;
    EXPECT_EQ(encoder_.Encode(s, 1, interval_ms_), pw::OkStatus());
    SleepUntilDone();
    Expect("..--..");
  }
}
#endif  // AM_MORSE_CODE_ENCODER_TEST_FULL

}  // namespace sense
