/**
 * @file    shot_captre.h
 * @brief   Shot Capture module
 * @author
 * @date    Oct 16 2025
 * @version 0.0.1
 *
 * @section LICENSES
 * Copyright (C) Morgan Advanced Programmable Systems, Inc.
 */


#ifndef SHOT_CAPTURE_H_
#define SHOT_CAPTURE_H_

/*--------------------------------------------------------------------------------------------------
 * INCLUDE FILES
 *------------------------------------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>

#include <zephyr/kernel.h>
#include <zephyr/sys/util.h> /* Zephyr MIN() macro */

#include "../bsp/imu.h"
#include "../bsp/imu_reg.h"

#include "../lib/errno.h"
#include "../lib/debug.h"


/*--------------------------------------------------------------------------------------------------
 * MACROS & CONSTANTS
 *------------------------------------------------------------------------------------------------*/
#define SHOT_CAPTURE_TASK_STACK_SIZE   (1024)
#define SHOT_CAPTURE_THREAD_PRIORITY     (4)

#define SHOTDATA_DURATION_MIN          (2)
#define SHOTDATA_DURATION_MAX          (10)
#define GYRO_ODR_DEFAULT_HZ            (416)
#define ACCEL_ODR_DEFAULT_HZ           (416)
#define SHOTDATA_DURATION_DEFAULT      (4)
#define SHOTDATA_LOCATION_DEFAULT      (SHOTDATA_DURATION_DEFAULT / 2)
#define SAMPLE_SET_ODR_DEFAULT_HZ      MIN(GYRO_ODR_DEFAULT_HZ, ACCEL_ODR_DEFAULT_HZ)
#define BYTES_PER_SAMPLE_SET           (GYRO_ODR_DEFAULT_HZ / SAMPLE_SET_ODR_DEFAULT_HZ + ACCEL_ODR_DEFAULT_HZ / SAMPLE_SET_ODR_DEFAULT_HZ) * 3 * 2
#define WORDS_PER_SAMPLE_SET           (GYRO_ODR_DEFAULT_HZ / SAMPLE_SET_ODR_DEFAULT_HZ + ACCEL_ODR_DEFAULT_HZ / SAMPLE_SET_ODR_DEFAULT_HZ) * 3
#define SHOTDATA_SIZE_IN_BYTES_DEFAULT (SHOTDATA_DURATION_DEFAULT * SAMPLE_SET_ODR_DEFAULT_HZ * BYTES_PER_SAMPLE_SET)
#define BYTES_AFTER_SHOT_DEFAULT       (SHOTDATA_DURATION_DEFAULT - SHOTDATA_LOCATION_DEFAULT) * SAMPLE_SET_ODR_DEFAULT_HZ * BYTES_PER_SAMPLE_SET

#define SHOT_CAPTURE_FILENAME         ("shot_capture")


/*--------------------------------------------------------------------------------------------------
 * TYPE DEFINITIONS & ENUMERATIONS
 *------------------------------------------------------------------------------------------------*/
typedef struct FIFO_ring_buf_s {
    uint8_t  *buf;
    uint16_t write_ptr;
    uint16_t read_ptr;
    uint32_t loop_ctr;
} FIFO_ring_buf_s;

typedef struct shot_data_status {
    /* system up time in ms */
    uint32_t time;
    /* start location of shot data in the ring buffer */
    uint32_t start;
    /* location of the shot data sample in the ring buffer */
    uint32_t location;
    /* words per sample set */
    uint8_t words_per_sample_set;
    /* words per sample set */
    uint8_t bytes_per_sample_set;
    /* size of shot data in bytes */
    uint32_t size;
    /* bytes to read after shot data */
    uint32_t bytes_after_shot;
    /* ambient light intensity */
    uint32_t ambient_light_intensity;
    /* flag to determine if shot data has been marked */
    bool     marked;
    /* flag to determine if there are enough samples after shot data */
    bool     ready;
    /* flag to show if the shot data window is written in to the flash */
    bool     saved;
} shot_data_status_s;

typedef struct SHOT_CAPTURE_config {
    uint8_t                  shot_duration;
    uint8_t                  shot_location;
    LSM6DS3TR_C_FS_G_ABSTR_e fs_g;
    LSM6DS3TR_C_ODR_G_e      odr_g;
    LSM6DS3TR_C_FS_XL_e      fs_xl;
    LSM6DS3TR_C_ODR_XL_e     odr_xl;
    uint8_t                  tap_ths;
    LSM6DS3TR_C_QUIET_e      quiet_time;
    LSM6DS3TR_C_SHOCK_e      shock_time;
    uint32_t                 user_shot_cnt;
    uint32_t                 shot_cnt;
    uint8_t                  shot_capture_en;
} __attribute__((packed, aligned(1))) SHOT_CAPTURE_config_s;


/*--------------------------------------------------------------------------------------------------
 * GLOBAL VARIABLE DECLARATION
 *------------------------------------------------------------------------------------------------*/
extern volatile FIFO_ring_buf_s FIFO_ring_buf;
extern volatile shot_data_status_s shot_data;
extern struct k_mutex shot_data_mutex;
extern struct k_mutex FIFO_ring_buf_mutex;
extern struct k_mutex stat_mutex;


/*--------------------------------------------------------------------------------------------------
 * PUBLIC FUNCTION PROTOTYPES
 *------------------------------------------------------------------------------------------------*/
void SHOT_CAPTURE_init(void);

void SHOT_CAPTURE_tap_ths_set(uint8_t tap_ths);
void SHOT_CAPTURE_quiet_time_set(LSM6DS3TR_C_QUIET_e quiet_time);
void SHOT_CAPTURE_shock_time_set(LSM6DS3TR_C_SHOCK_e shock_time);

void SHOT_CAPTURE_shotdata_duration_location_set(uint8_t duration, uint8_t location);

SHOT_CAPTURE_config_s *SHOT_CAPTURE_config_get(void);

ERRNO_e SHOT_CAPTURE_enable(bool enable);

bool SHOT_CAPTURE_is_enabled(void);

ERRNO_e SHOT_CAPTURE_save_shot_cnt(void);

void SHOT_CAPTURE_task_install(void);

/**
 * @brief Disable shot capture and wait until the capture task is confirmed idle.
 *        Must NOT be called from _shot_capture_task itself.
 */
void SHOT_CAPTURE_task_disable_and_wait(void);

void SHOT_CAPTURE_task_resume(void);

void SHOT_CAPTURE_cli_cmd(int32_t argc, char **argv);


#endif /* SHOT_CAPTURE_H */