// 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/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().IgnorePoll();
      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::Dispatcher 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
