/*
  FastLED — Null ISR Implementation (Weak Symbols)
  ------------------------------------------------
  Default null implementation of the cross-platform ISR API using weak symbols.
  This provides a fallback when no platform-specific implementation is available.

  Platform-specific implementations (ESP32, Teensy, AVR, etc.) provide strong
  symbol overrides that replace these weak defaults at link time.

  License: MIT (FastLED)
*/

#pragma once

#include "fl/stl/isr/handler.h"
#include "fl/stl/compiler_control.h"
#include "fl/stl/noexcept.h"

namespace fl {
namespace isr {

// Platform ID for null implementation
constexpr u8 NULL_PLATFORM_ID = 255;  // Indicates "no platform"

// Error code for not implemented
constexpr int ERR_NOT_IMPLEMENTED = -100;

// =============================================================================
// Null ISR Implementation (Free Functions)
// =============================================================================

/**
 * Null implementation that provides safe no-op defaults.
 * Used when no platform-specific ISR implementation is available.
 */

inline int null_attach_timer_handler(const isr_config_t& config, isr_handle_t* out_handle) FL_NOEXCEPT {
    (void)config;
    if (out_handle) {
        *out_handle = isr_handle_t();  // Invalid handle
    }
    return ERR_NOT_IMPLEMENTED;  // Not implemented error
}

inline int null_attach_external_handler(u8 pin, const isr_config_t& config, isr_handle_t* out_handle) FL_NOEXCEPT {
    (void)pin;
    (void)config;
    if (out_handle) {
        *out_handle = isr_handle_t();  // Invalid handle
    }
    return ERR_NOT_IMPLEMENTED;  // Not implemented error
}

inline int null_detach_handler(isr_handle_t& handle) FL_NOEXCEPT {
    handle = isr_handle_t();  // Invalidate handle
    return ERR_NOT_IMPLEMENTED;  // Not implemented error
}

inline int null_enable_handler(isr_handle_t& handle) FL_NOEXCEPT {
    (void)handle;
    return ERR_NOT_IMPLEMENTED;  // Not implemented error
}

inline int null_disable_handler(isr_handle_t& handle) FL_NOEXCEPT {
    (void)handle;
    return ERR_NOT_IMPLEMENTED;  // Not implemented error
}

inline bool null_is_handler_enabled(const isr_handle_t& handle) FL_NOEXCEPT {
    (void)handle;
    return false;
}

inline const char* null_get_error_string(int error_code) FL_NOEXCEPT {
    switch (error_code) {
        case 0: return "Success";
        case ERR_NOT_IMPLEMENTED: return "Not implemented (no platform ISR support)";
        default: return "Unknown error";
    }
}

inline const char* null_get_platform_name() FL_NOEXCEPT {
    return "Null";
}

inline u32 null_get_max_timer_frequency() FL_NOEXCEPT {
    return 0;  // No timer support
}

inline u32 null_get_min_timer_frequency() FL_NOEXCEPT {
    return 0;  // No timer support
}

inline u8 null_get_max_priority() FL_NOEXCEPT {
    return 0;  // No priority support
}

inline bool null_requires_assembly_handler(u8 priority) FL_NOEXCEPT {
    (void)priority;
    return false;
}

} // namespace isr

// fl::isr::platform namespace wrappers (call fl::isr:: functions)
// The dispatch header (platforms/isr.h) controls when this file is included,
// so we unconditionally define the platform namespace here.
namespace isr {
namespace platforms {

inline int attach_timer_handler(const isr_config_t& config, isr_handle_t* handle) FL_NOEXCEPT {
    return null_attach_timer_handler(config, handle);
}

inline int attach_external_handler(u8 pin, const isr_config_t& config, isr_handle_t* handle) FL_NOEXCEPT {
    return null_attach_external_handler(pin, config, handle);
}

inline int detach_handler(isr_handle_t& handle) FL_NOEXCEPT {
    return null_detach_handler(handle);
}

inline int enable_handler(isr_handle_t& handle) FL_NOEXCEPT {
    return null_enable_handler(handle);
}

inline int disable_handler(isr_handle_t& handle) FL_NOEXCEPT {
    return null_disable_handler(handle);
}

inline bool is_handler_enabled(const isr_handle_t& handle) FL_NOEXCEPT {
    return null_is_handler_enabled(handle);
}

inline const char* get_error_string(int error_code) FL_NOEXCEPT {
    return null_get_error_string(error_code);
}

inline const char* get_platform_name() FL_NOEXCEPT {
    return null_get_platform_name();
}

inline u32 get_max_timer_frequency() FL_NOEXCEPT {
    return null_get_max_timer_frequency();
}

inline u32 get_min_timer_frequency() FL_NOEXCEPT {
    return null_get_min_timer_frequency();
}

inline u8 get_max_priority() FL_NOEXCEPT {
    return null_get_max_priority();
}

inline bool requires_assembly_handler(u8 priority) FL_NOEXCEPT {
    return null_requires_assembly_handler(priority);
}

} // namespace platforms
} // namespace isr

// =============================================================================
// Global Interrupt Control (noInterrupts/interrupts)
// =============================================================================

// Only define if not already provided by a platform-specific header
// (e.g., isr_avr.hpp defines these for all AVR including ATtiny)
#ifndef FL_ISR_GLOBAL_INTERRUPTS_DEFINED

/// No-op for null/unsupported platform
inline void interruptsDisable() FL_NOEXCEPT {
    // No-op: platform doesn't have ISR support
}

/// No-op for null/unsupported platform
inline void interruptsEnable() FL_NOEXCEPT {
    // No-op: platform doesn't have ISR support
}

#endif // FL_ISR_GLOBAL_INTERRUPTS_DEFINED

} // namespace fl
