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

#include <signal.h>
#include <stdio.h>
#include <unistd.h>

#include "modules/air_sensor/air_sensor_fake.h"
#include "modules/board/board_fake.h"
#include "modules/light/fake_sensor.h"
#include "modules/proximity/fake_sensor.h"
#include "pw_assert/check.h"
#include "pw_channel/stream_channel.h"
#include "pw_digital_io/digital_io.h"
#include "pw_multibuf/simple_allocator.h"
#include "pw_system/io.h"
#include "pw_system/system.h"
#include "pw_thread_stl/options.h"

using ::pw::channel::StreamChannel;
using ::pw::digital_io::DigitalIn;
using ::pw::digital_io::State;

extern "C" {

void CtrlCSignalHandler(int /* ignored */) {
  printf("\nCtrl-C received; simulator exiting immediately...\n");
  // Skipping the C++ destructors since we want to exit immediately.
  _exit(0);
}

}  // extern "C"

void InstallCtrlCSignalHandler() {
  // Catch Ctrl-C to force a 0 exit code (success) to avoid signaling an error
  // for intentional exits. For example, VSCode shows an alarming dialog on
  // non-zero exit, which is confusing for users intentionally quitting.
  signal(SIGINT, CtrlCSignalHandler);
}

namespace {
class VirtualInput : public DigitalIn {
 public:
  VirtualInput(State state) : state_(state) {}

 private:
  pw::Status DoEnable(bool) override { return pw::OkStatus(); }
  pw::Result<State> DoGetState() override { return state_; }

  State state_;
};

VirtualInput io_sw_a(State::kInactive);
VirtualInput io_sw_b(State::kInactive);
VirtualInput io_sw_x(State::kInactive);
VirtualInput io_sw_y(State::kInactive);

}  // namespace

namespace sense::system {

void Init() {}

void Start() {
  InstallCtrlCSignalHandler();
  printf("=====================================\n");
  printf("=== Pigweed Sense: Host Simulator ===\n");
  printf("=====================================\n");
  printf("Simulator is now running. To connect with a console,\n");
  printf("either run one in a new terminal:\n");
  printf("\n");
  printf("   $ bazelisk run //<app>:simulator_console\n");
  printf("\n");
  printf("where <app> is e.g. blinky, factory, or production, or launch\n");
  printf("one from VSCode under the 'Bazel Build Targets' explorer tab.\n");
  printf("\n");
  printf("Press Ctrl-C to exit\n");

  static std::byte channel_buffer[16384];
  static pw::multibuf::SimpleAllocator multibuf_alloc(channel_buffer,
                                                      pw::System().allocator());
  static pw::NoDestructor<StreamChannel> channel(multibuf_alloc,
                                                 pw::system::GetReader(),
                                                 pw::thread::stl::Options(),
                                                 pw::system::GetWriter(),
                                                 pw::thread::stl::Options());

  pw::SystemStart(*channel);
  PW_UNREACHABLE;
}

sense::AirSensor& AirSensor() {
  static AirSensorFake air_sensor;
  return air_sensor;
}

sense::Board& Board() {
  static BoardFake board;
  return board;
}

sense::ButtonManager& ButtonManager() {
  static ::sense::ButtonManager manager(io_sw_a, io_sw_b, io_sw_x, io_sw_y);
  return manager;
}

sense::AmbientLightSensor& AmbientLightSensor() {
  static ::sense::FakeAmbientLightSensor fake_light;
  return fake_light;
}

sense::ProximitySensor& ProximitySensor() {
  static ::sense::FakeProximitySensor fake_prox;
  return fake_prox;
}

}  // namespace sense::system
