// 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 "modules/worker/test_worker.h"
#include "pw_containers/vector.h"
#include "pw_status/status.h"
#include "pw_sync/timed_thread_notification.h"
#include "pw_thread/sleep.h"
#include "pw_thread/thread.h"
#include "pw_unit_test/framework.h"

namespace sense {

// Test fixtures.

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

  static constexpr uint32_t kIntervalMs = 10;

  // TODO(b/352327457): Ideally this would use simulated time, but no
  // simulated system timer exists yet. For now, relax the constraint by
  // checking that the LED was in the right state for _at least_ the expected
  // number of intervals. On some platforms, the fake LED is implemented using
  // threads, and may sleep a bit longer.
  MorseCodeEncoderTest()
      : clock_(pw::chrono::VirtualSystemClock::RealClock()) {}

  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 roght 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() {
    auto interval = pw::chrono::SystemClock::for_at_least(
        std::chrono::milliseconds(interval_ms_));
    while (!encoder_.IsIdle()) {
      pw::this_thread::sleep_for(interval);
    }
  }

  auto LedOutput() {
    return [this](bool turn_on, const Encoder::State& state) {
      FakeLedOutput(turn_on, state.message_finished());
    };
  }

  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::chrono::VirtualSystemClock& clock_;
  MonochromeLedFake led_;
  int end_of_pattern_count_ = 0;
};

// Unit tests.

TEST_F(MorseCodeEncoderTest, EncodeEmpty) {
  TestWorker<> worker;
  encoder_.Init(worker, LedOutput());
  expected_messages_ = 0;
  EXPECT_EQ(encoder_.Encode("", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  worker.Stop();
  Expect("");
}

TEST_F(MorseCodeEncoderTest, EncodeOneLetter) {
  TestWorker<> worker;
  encoder_.Init(worker, LedOutput());
  EXPECT_EQ(encoder_.Encode("E", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  worker.Stop();
  Expect(".");
}

TEST_F(MorseCodeEncoderTest, EncodeOneWord) {
  TestWorker<> worker;
  encoder_.Init(worker, LedOutput());
  EXPECT_EQ(encoder_.Encode("PARIS", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  worker.Stop();
  Expect(".--. .- .-. .. ...");
}

TEST_F(MorseCodeEncoderTest, EncodeHelloWorld) {
  TestWorker<> worker;
  encoder_.Init(worker, LedOutput());
  EXPECT_EQ(encoder_.Encode("hello world", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  worker.Stop();

  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) {
  TestWorker<> worker;
  encoder_.Init(worker, LedOutput());
  expected_messages_ = 2;
  EXPECT_EQ(encoder_.Encode("hello", 2, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  worker.Stop();
  Expect(".... . .-.. .-.. ---  .... . .-.. .-.. ---");
}

TEST_F(MorseCodeEncoderTest, EncodeSlow) {
  TestWorker<> worker;
  encoder_.Init(worker, LedOutput());
  interval_ms_ = 25;
  EXPECT_EQ(encoder_.Encode("hello", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  worker.Stop();
  Expect(".... . .-.. .-.. ---");
}

TEST_F(MorseCodeEncoderTest, EncodeConsecutiveWhitespace) {
  TestWorker<> worker;
  encoder_.Init(worker, LedOutput());
  EXPECT_EQ(encoder_.Encode("hello    world", 1, interval_ms_), pw::OkStatus());
  SleepUntilDone();
  worker.Stop();
  Expect(".... . .-.. .-.. ---  .-- --- .-. .-.. -..");
}

TEST_F(MorseCodeEncoderTest, EncodeInvalidChars) {
  TestWorker<> worker;
  encoder_.Init(worker, LedOutput());
  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("..--..");
  }
  worker.Stop();
}
#endif  // AM_MORSE_CODE_ENCODER_TEST_FULL

}  // namespace sense
