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