PRO read_ihsafe, input_file
; $Id: read_ihsafe.pro,v 1.4 2026/04/01 16:31:27 nathan Exp $
  ;+
  ; NAME:
  ;   read_and_print_ihsafe
  ;
  ; PURPOSE:
  ;   This procedure reads a hex-dump file containing IH_SAFETY table data,
  ;   parses it according to the structure described in ih_autonRule_desc.htm,
  ;   and prints the converted values in a formatted table to a file.
  ;
  ; CALLING SEQUENCE:
  ;   read_and_print_ihsafe, 'ihsafe26.txt'
  ;
  ; INPUTS:
  ;   input_file:  The path to the input data file (e.g., 'ihsafe26.txt').
  ;
  ; OUTPUTS:
  ;	summary.txt file in same directory as input
  ;
  ; SIDE EFFECTS:
  ;   Prints a formatted table to the standard output.
  ;
  ; NOTES:
  ;   The parsing logic is based on the IH_SAFETY table description:
  ;   - Each record is 60 bytes.
  ;   - 15 x 2-byte (16-bit) integer values.
  ;   - 1 x 30-byte ASCII string.
  ;   - Integer values are assumed to be big-endian in the hex dump.
  ;-

; get output filename
break_file,input_file,di,pa,fi,sf
outfile=pa+fi+"_summary.txt"
openw,1,outfile

  ; Open the input file for reading
  OPENR, in_lun, input_file, /GET_LUN
  
  ; Define the header strings and format
  header_str = 'RuleNum CompType Limit Interval PersThresh PersWin APID Byte Bit Length ConvIndx EvType ActionNum ActionMd Enab RuleName'
  pheader = 'RuleNum Limit Enabled RuleName'
  ; Print table header
  PRINTf,1, header_str
  PRINTf,1,    '------------------------------------------------------------------------------------------------------------------------'
      print,pheader 
      print,'--------------------------------'
	
  line = ''
  
  ; Loop through each line in the input file
  WHILE NOT EOF(in_lun) DO BEGIN
    READF, in_lun, line

    ; Skip comment lines and empty lines
    IF (STRMID(line, 0, 1) EQ ';') OR (STRTRIM(line, 2) EQ '') THEN CONTINUE

    ; Process data lines (starting with 'X')
    IF STRMID(line, 0, 1) EQ 'X' THEN BEGIN

      ; Remove the 'X' prefix and split by spaces to get individual hex bytes
      data_str = STRTRIM(STRMID(line, 1), 2)
      hex_parts = STRSPLIT(data_str, ' ', /EXTRACT)

      ; A valid record should have at least 60 bytes (hex parts)
      IF N_ELEMENTS(hex_parts) GE 60 THEN BEGIN
        
        rule_num_h = hex_parts[0] + hex_parts[1]
        READS, rule_num_h, rule_num, FORMAT='(Z)'

        ; Only process lines that appear to contain data
        IF rule_num NE 0 THEN BEGIN

            comp_type_h = hex_parts[2] + hex_parts[3]
            READS, comp_type_h, comp_type, FORMAT='(Z)'
            
            ; Limit is a signed 16-bit value
            limit_h = hex_parts[4] + hex_parts[5]
            READS, limit_h, limit_raw, FORMAT='(Z)'
            limit_val = (limit_raw GT 32767L) ? (limit_raw - 65536L) : limit_raw

            eval_int_h = hex_parts[6] + hex_parts[7]
            READS, eval_int_h, eval_int, FORMAT='(Z)'

            pers_thr_h = hex_parts[8] + hex_parts[9]
            READS, pers_thr_h, pers_thr, FORMAT='(Z)'

            pers_win_h = hex_parts[10] + hex_parts[11]
            READS, pers_win_h, pers_win, FORMAT='(Z)'

            apid_h = hex_parts[12] + hex_parts[13]
            READS, apid_h, apid, FORMAT='(Z)'

            start_byte_h = hex_parts[14] + hex_parts[15]
            READS, start_byte_h, start_byte, FORMAT='(Z)'

            start_bit_h = hex_parts[16] + hex_parts[17]
            READS, start_bit_h, start_bit, FORMAT='(Z)'
            
            bit_len_h = hex_parts[18] + hex_parts[19]
            READS, bit_len_h, bit_len, FORMAT='(Z)'

            conv_idx_h = hex_parts[20] + hex_parts[21]
            READS, conv_idx_h, conv_idx, FORMAT='(Z)'

            evt_type_h = hex_parts[22] + hex_parts[23]
            READS, evt_type_h, evt_type, FORMAT='(Z)'

            act_num_h = hex_parts[24] + hex_parts[25]
            READS, act_num_h, act_num, FORMAT='(Z)'

            act_mode_h = hex_parts[26] + hex_parts[27]
            READS, act_mode_h, act_mode, FORMAT='(Z)'

            enb_mode_h = hex_parts[28] + hex_parts[29]
            READS, enb_mode_h, enb_mode, FORMAT='(Z)'

            ; --- Parse the 30-byte string field ---
            str_bytes = BYTARR(30)
            FOR i=0,29 DO BEGIN
                val_h = '00' + hex_parts[30+i]
                READS, val_h, byte_val, FORMAT='(Z)'
                str_bytes[i] = byte_val
            ENDFOR
            
            ; Find the first null character to correctly terminate the string
            null_pos = WHERE(str_bytes EQ 0, count)
            IF count GT 0 THEN BEGIN
              rule_name = STRING(str_bytes[0:null_pos[0]-1])
            ENDIF ELSE BEGIN
              rule_name = STRING(str_bytes)
            ENDELSE

            ; --- Print the parsed record ---
	print,rule_num, limit_val / 100.0,  enb_mode, '  ',rule_name
            PRINTf,1, FORMAT='(I-8, " ", I-8, " ", F-8.2, " ", I-8, " ", I-8, " ", I-8, " ", I-8, " ", I-9, " ", I-8, " ", I-8, " ", I-8, " ", I-8, " ", I-8, " ", I-8, " ", I-8, " ", A)', $
                rule_num, comp_type, limit_val / 100.0, eval_int, pers_thr, pers_win, apid, $
                start_byte, start_bit, bit_len, conv_idx, evt_type, act_num, $
                act_mode, enb_mode, rule_name

        ENDIF
      ENDIF
    ENDIF
  ENDWHILE

  ; Close the files
  FREE_LUN, in_lun
  close,1

END

; $Log: read_ihsafe.pro,v $
; Revision 1.4  2026/04/01 16:31:27  nathan
; fixes
;
; Revision 1.3  2026/04/01 16:25:40  nathan
; fixes
;
; Revision 1.2  2026/04/01 16:24:30  nathan
; updates/fixes
;
; Revision 1.1  2026/04/01 15:57:27  nathan
; modified from AI first draft
;
