#pragma once

#include "../Common/can_mv.hpp"
#include "../Common/df_player.hpp"
#include "../Common/hc05.hpp"
#include "../Common/ultrasonic.hpp"
#include "../config.hpp"
#include "Common/serial_port.hpp"

class CommonCenter {
public:
    CommonCenter()                               = delete;
    CommonCenter(const CommonCenter&)            = delete;
    CommonCenter& operator=(const CommonCenter&) = delete;

    static Ultrasonic& GetUltrasonic() {
        static Ultrasonic* instance = nullptr;
        if (instance == nullptr) {
            instance = new Ultrasonic(
                Config::kCaptureConfig.trigger, Config::kCaptureConfig.timer, Config::kCaptureConfig.channel);
        }
        return *instance;
    }

    static DfPlayer& GetDfPlayer() {
        static DfPlayer* instance = nullptr;
        if (instance == nullptr) {
            instance = new DfPlayer(Config::kDfPlayerUart);
        }
        return *instance;
    }

    static CanMv& GetCanMv() {
        static CanMv* instance = nullptr;
        if (instance == nullptr) {
            instance = new CanMv(Config::kCanMvUart);
        }
        return *instance;
    }

    static Hc05& GetHc05() {
        static Hc05* instance = nullptr;
        if (instance == nullptr) {
            instance = new Hc05(Config::kHc05Uart);
        }
        return *instance;
    }

    static SerialPort& GetDebugSerialPort() {
        static constexpr auto kBaudRate = 115200;
        static constexpr auto kLength   = 256;
        static constexpr auto kTimeout  = 1000;
        static SerialPort* instance     = nullptr;
        if (instance == nullptr) {
            instance = new SerialPort(Config::kDebugUart, kBaudRate, kLength, kTimeout);
        }
        return *instance;
    }
};
