/*
  HardwareTimer.h - Hardware Timer interface for Arduino
  Copyright (c) 2025 Arduino LLC.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
*/

#pragma once

#include <inttypes.h>
#include <functional>
#include <pthread.h>
#include "drv_timer.h"

namespace arduino {

class HardwareTimer {
protected:
    drv_hard_timer_inst_t* timer_inst;
    uint8_t timer_id;

    bool is_initialized;
    bool is_started;
    bool auto_reload;

    uint32_t frequency;
    uint32_t period_ms;

    std::function<void()> user_callback;
    std::function<void(void*)> user_callback_arg;
    void* user_arg;

#if !CONFIG_DISABLE_HAL_LOCKS
    pthread_mutex_t _lock;
    pthread_mutex_t *lock;
#endif

private:
    static void timerISRHandler(void* args);

public:
    HardwareTimer(uint8_t timer_num);
    ~HardwareTimer();

    // Initialize timer with frequency (Hz)
    bool begin(uint32_t freq_hz = 12500000);  // Default 12.5MHz
    bool end();

    // Timer control functions
    bool start();
    bool stop();
    bool restart();

    // Configuration functions
    bool setMode(bool auto_reload);  // true for periodic, false for one-shot
    bool setFrequency(uint32_t freq_hz);
    bool setPeriod(uint32_t period_ms);
    bool setAlarm(uint32_t alarm_ms);  // Set alarm in milliseconds

    // Get timer info
    uint32_t getFrequency();
    uint32_t getPeriod();
    uint8_t getTimerId() { return timer_id; }
    bool isStarted() { return is_started; }

    // Interrupt handling
    void attachInterrupt(const std::function<void()>& callback);
    void attachInterruptArg(const std::function<void(void*)>& callback, void* arg);
    void detachInterrupt();
};

// Global timer instances
extern HardwareTimer Timer0;
extern HardwareTimer Timer1;
extern HardwareTimer Timer2;
extern HardwareTimer Timer3;
extern HardwareTimer Timer4;
extern HardwareTimer Timer5;

} // namespace arduino

using namespace arduino;
