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

#include <array>

#include "modules/led/polychrome_led_fake.h"
#include "modules/pubsub/pubsub.h"
#include "modules/pubsub/pubsub_events.h"
#include "modules/worker/test_worker.h"
#include "pw_chrono/system_clock.h"
#include "pw_thread/sleep.h"
#include "pw_unit_test/framework.h"

namespace sense {

using namespace std::chrono_literals;

class StateManagerTest : public ::testing::Test {
 protected:
  StateManagerTest()
      : ::testing::Test(),
        pubsub_(worker_),
        state_manager_(pubsub_, led_),
        event_(TimerExpired{.token = 0}) {}

  void SetUp() override {
    reference_led_.SetColor(0);
    reference_led_.SetBrightness(AmbientLightAdjustedLed::kDefaultBrightness);
    reference_led_.Enable();
    reference_led_.TurnOn();
    led_.EnableWaiting();
  }

  void SetExpectedColor(uint16_t air_quality) {
    auto led_value = AirSensor::GetLedValue(air_quality);
    reference_led_.SetColor(led_value.r(), led_value.g(), led_value.b());
  }
  void SetExpectedColor(AirSensor::Score air_quality) {
    SetExpectedColor(static_cast<uint16_t>(air_quality));
  }
  void SetExpectedBrightness(uint8_t brightness) {
    reference_led_.SetBrightness(brightness);
  }
  uint16_t GetExpectedRed() { return reference_led_.red(); }
  uint16_t GetExpectedGreen() { return reference_led_.green(); }
  uint16_t GetExpectedBlue() { return reference_led_.blue(); }

  void TearDown() override { worker_.Stop(); }

  TestWorker<> worker_;
  GenericPubSubBuffer<Event, 20, 10> pubsub_;
  PolychromeLedFake led_;
  StateManager state_manager_;
  Event event_;
  pw::sync::ThreadNotification morse_encode_request_;
  pw::sync::ThreadNotification timer_request_;
  pw::sync::ThreadNotification state_update_notification_;

 private:
  PolychromeLedFake reference_led_;
};

TEST_F(StateManagerTest, UpdateAirQuality) {
  uint16_t air_quality = 800;
  ASSERT_TRUE(pubsub_.Publish(AirQuality{.score = air_quality}));
  led_.Await();
  SetExpectedColor(air_quality);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
}

TEST_F(StateManagerTest, MorseReadout) {
  ASSERT_TRUE(pubsub_.SubscribeTo<SenseState>(
      [this](SenseState) { state_update_notification_.release(); }));

  // The manager needs at least one score to switch to Morce code mode.
  uint16_t air_quality = 800;
  ASSERT_TRUE(pubsub_.Publish(AirQuality{.score = air_quality}));
  led_.Await();
  state_update_notification_.acquire();

  ASSERT_TRUE(pubsub_.SubscribeTo<MorseEncodeRequest>(
      [this](MorseEncodeRequest) { morse_encode_request_.release(); }));
  ASSERT_TRUE(pubsub_.Publish(ButtonY(true)));
  morse_encode_request_.acquire();
  state_update_notification_.acquire();

  // Responds to Morse code edges.
  EXPECT_TRUE(led_.is_on());
  ASSERT_TRUE(pubsub_.Publish(
      MorseCodeValue{.turn_on = false, .message_finished = false}));
  led_.Await();
  EXPECT_FALSE(led_.is_on());
}

TEST_F(StateManagerTest, UpdateAirQualityAndTriggerAlarm) {
  ASSERT_TRUE(pubsub_.SubscribeTo<MorseEncodeRequest>(
      [this](MorseEncodeRequest) { morse_encode_request_.release(); }));

  uint16_t air_quality = 100;
  ASSERT_TRUE(pubsub_.Publish(AirQuality{.score = air_quality}));
  led_.Await();

  SetExpectedColor(air_quality);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());

  // Alarm triggered; responds to Morse code edges.
  morse_encode_request_.acquire();
  ASSERT_TRUE(pubsub_.Publish(
      MorseCodeValue{.turn_on = false, .message_finished = false}));
  led_.Await();
  EXPECT_FALSE(led_.is_on());
}

TEST_F(StateManagerTest, UpdateAirQualityAndDisableAlarm) {
  ASSERT_TRUE(pubsub_.SubscribeTo<MorseEncodeRequest>(
      [this](MorseEncodeRequest) { morse_encode_request_.release(); }));
  ASSERT_TRUE(pubsub_.SubscribeTo<SenseState>(
      [this](SenseState) { state_update_notification_.release(); }));

  // Alarm triggered; responds to Morse code edges.
  uint16_t air_quality = 200;
  ASSERT_TRUE(pubsub_.Publish(AirQuality{.score = air_quality}));
  led_.Await();
  state_update_notification_.acquire();

  // Alarm triggered; responds to Morse code edges.
  morse_encode_request_.acquire();
  ASSERT_TRUE(pubsub_.Publish(
      MorseCodeValue{.turn_on = false, .message_finished = true}));
  led_.Await();
  EXPECT_FALSE(led_.is_on());

  air_quality = 1000;
  ASSERT_TRUE(pubsub_.Publish(AirQuality{.score = air_quality}));
  led_.Await();
  state_update_notification_.acquire();

  // The state manager updates the LED before disabling the alarm. There's no
  // other event to synchronize on, so send another update to synchronize on
  // and ensure the state change is complete.
  ASSERT_TRUE(pubsub_.Publish(AirQuality{.score = air_quality}));
  led_.Await();
  state_update_notification_.acquire();

  // Don't check for a specific color. The air quality score is smoothed
  // exponentially, so only check that the alarm is disabled and the LED is on.
  EXPECT_TRUE(led_.is_on());
}

TEST_F(StateManagerTest, SilenceAlarm) {
  ASSERT_TRUE(pubsub_.SubscribeTo<MorseEncodeRequest>(
      [this](MorseEncodeRequest) { morse_encode_request_.release(); }));
  ASSERT_TRUE(pubsub_.SubscribeTo<SenseState>(
      [this](SenseState) { state_update_notification_.release(); }));

  // Trigger an alarm.
  ASSERT_TRUE(pubsub_.Publish(AirQuality{.score = 100}));
  led_.Await();
  state_update_notification_.acquire();

  // Alarm triggered; responds to Morse code edges.
  morse_encode_request_.acquire();
  EXPECT_TRUE(led_.is_on());
  ASSERT_TRUE(pubsub_.Publish(
      MorseCodeValue{.turn_on = false, .message_finished = false}));
  led_.Await();
  EXPECT_FALSE(led_.is_on());

  // Disable alarm.
  ASSERT_TRUE(pubsub_.Publish(ButtonX(true)));

  ASSERT_TRUE(pubsub_.Publish(AirQuality{.score = 100}));
  led_.Await();
  state_update_notification_.acquire();

  // Alarm disabled; does not respond to Morse code events
  EXPECT_TRUE(led_.is_on());
  ASSERT_TRUE(pubsub_.Publish(
      MorseCodeValue{.turn_on = false, .message_finished = false}));
  EXPECT_FALSE(led_.TryAwaitFor(100ms));
  EXPECT_TRUE(led_.is_on());
}

TEST_F(StateManagerTest, IncrementThresholdAndTimeout) {
  ASSERT_TRUE(pubsub_.SubscribeTo<TimerRequest>([this](TimerRequest request) {
    event_ = request;
    timer_request_.release();
  }));
  ASSERT_TRUE(pubsub_.SubscribeTo<MorseEncodeRequest>(
      [this](MorseEncodeRequest) { morse_encode_request_.release(); }));
  ASSERT_TRUE(pubsub_.SubscribeTo<SenseState>(
      [this](SenseState) { state_update_notification_.release(); }));

  ASSERT_TRUE(pubsub_.Publish(ButtonB(true)));
  led_.Await();
  SetExpectedColor(AirSensor::Score::kYellow);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());

  timer_request_.acquire();
  TimerRequest request = std::get<TimerRequest>(event_);
  EXPECT_EQ(request.token, StateManager::kThresholdModeToken);
  EXPECT_EQ(request.timeout_s, StateManager::kThresholdModeTimeout);

  ASSERT_TRUE(pubsub_.Publish(ButtonA(true)));
  led_.Await();
  SetExpectedColor(AirSensor::Score::kLightGreen);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
  timer_request_.acquire();
  request = std::get<TimerRequest>(event_);
  EXPECT_EQ(request.token, StateManager::kThresholdModeToken);
  EXPECT_EQ(request.timeout_s, StateManager::kThresholdModeTimeout);

  ASSERT_TRUE(pubsub_.Publish(ButtonA(true)));
  led_.Await();
  SetExpectedColor(AirSensor::Score::kGreen);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
  timer_request_.acquire();
  request = std::get<TimerRequest>(event_);
  EXPECT_EQ(request.token, StateManager::kThresholdModeToken);
  EXPECT_EQ(request.timeout_s, StateManager::kThresholdModeTimeout);

  ASSERT_TRUE(pubsub_.Publish(ButtonA(true)));
  led_.Await();
  SetExpectedColor(AirSensor::Score::kBlueGreen);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
  timer_request_.acquire();
  request = std::get<TimerRequest>(event_);
  EXPECT_EQ(request.token, StateManager::kThresholdModeToken);
  EXPECT_EQ(request.timeout_s, StateManager::kThresholdModeTimeout);

  ASSERT_TRUE(pubsub_.Publish(ButtonA(true)));
  led_.Await();
  SetExpectedColor(AirSensor::Score::kCyan);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
  timer_request_.acquire();
  request = std::get<TimerRequest>(event_);
  EXPECT_EQ(request.token, StateManager::kThresholdModeToken);
  EXPECT_EQ(request.timeout_s, StateManager::kThresholdModeTimeout);

  // At max threshold; cannot increase further.
  ASSERT_TRUE(pubsub_.Publish(ButtonA(true)));
  SetExpectedColor(AirSensor::Score::kCyan);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
  timer_request_.acquire();
  request = std::get<TimerRequest>(event_);
  EXPECT_EQ(request.token, StateManager::kThresholdModeToken);
  EXPECT_EQ(request.timeout_s, StateManager::kThresholdModeTimeout);

  // Now time out of the threshold mode.
  ASSERT_TRUE(pubsub_.Publish(
      TimerExpired{.token = StateManager::kThresholdModeToken}));
  morse_encode_request_.acquire();
  state_update_notification_.acquire();
}

TEST_F(StateManagerTest, DecrementThresholdAndTimeout) {
  ASSERT_TRUE(pubsub_.SubscribeTo<TimerRequest>([this](TimerRequest request) {
    event_ = request;
    timer_request_.release();
  }));
  ASSERT_TRUE(pubsub_.SubscribeTo<MorseEncodeRequest>(
      [this](MorseEncodeRequest) { morse_encode_request_.release(); }));
  ASSERT_TRUE(pubsub_.SubscribeTo<SenseState>(
      [this](SenseState) { state_update_notification_.release(); }));

  ASSERT_TRUE(pubsub_.Publish(ButtonA(true)));
  led_.Await();
  SetExpectedColor(AirSensor::Score::kYellow);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
  timer_request_.acquire();
  TimerRequest request = std::get<TimerRequest>(event_);
  EXPECT_EQ(request.token, StateManager::kThresholdModeToken);
  EXPECT_EQ(request.timeout_s, StateManager::kThresholdModeTimeout);

  ASSERT_TRUE(pubsub_.Publish(ButtonB(true)));
  led_.Await();
  SetExpectedColor(AirSensor::Score::kOrange);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
  timer_request_.acquire();
  request = std::get<TimerRequest>(event_);
  EXPECT_EQ(request.token, StateManager::kThresholdModeToken);
  EXPECT_EQ(request.timeout_s, StateManager::kThresholdModeTimeout);

  ASSERT_TRUE(pubsub_.Publish(ButtonB(true)));
  led_.Await();
  SetExpectedColor(AirSensor::Score::kRed);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
  timer_request_.acquire();
  request = std::get<TimerRequest>(event_);
  EXPECT_EQ(request.token, StateManager::kThresholdModeToken);
  EXPECT_EQ(request.timeout_s, StateManager::kThresholdModeTimeout);

  // At min threshold; cannot decrease further.
  ASSERT_TRUE(pubsub_.Publish(ButtonB(true)));
  SetExpectedColor(AirSensor::Score::kRed);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
  timer_request_.acquire();
  request = std::get<TimerRequest>(event_);
  EXPECT_EQ(request.token, StateManager::kThresholdModeToken);
  EXPECT_EQ(request.timeout_s, StateManager::kThresholdModeTimeout);

  // Now time out of the threshold mode.
  ASSERT_TRUE(pubsub_.Publish(
      TimerExpired{.token = StateManager::kThresholdModeToken}));
  morse_encode_request_.acquire();
  state_update_notification_.acquire();
}

TEST_F(StateManagerTest, AdjustBrightness) {
  ASSERT_TRUE(pubsub_.Publish(AmbientLightSample{.sample_lux = 2000.f}));
  led_.Await();
}

TEST_F(StateManagerTest, AdjustBrightnessMin) {
  ASSERT_TRUE(pubsub_.Publish(AmbientLightSample{.sample_lux = 20.f}));
  led_.Await();
  SetExpectedBrightness(AmbientLightAdjustedLed::kMinBrightness);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
}

TEST_F(StateManagerTest, AdjustBrightnessMax) {
  ASSERT_TRUE(pubsub_.Publish(AmbientLightSample{.sample_lux = 20000.f}));
  led_.Await();
  SetExpectedBrightness(AmbientLightAdjustedLed::kMaxBrightness);
  EXPECT_EQ(led_.red(), GetExpectedRed());
  EXPECT_EQ(led_.green(), GetExpectedGreen());
  EXPECT_EQ(led_.blue(), GetExpectedBlue());
}

}  // namespace sense
