#include <string.h>
#include <stdio.h>
#include "messagerie.h"

#define NB_MAX_MESSAGE 30

int index_message=0;
struct message_t message_liste[NB_MAX_MESSAGE];

/// @brief Renvoi 1 si des message sont disponibles
/// @return 
bool message_disponible(){
  return (index_message != 0);
}

/// @brief Renvoi un message à traiter, à n'appeler que si message_disponible() renvoie 1
/// @return Message
struct message_t get_message(){
  index_message = index_message - 1;
  return message_liste[index_message];
}

void put_message(struct message_t message){
  if(index_message < NB_MAX_MESSAGE-1){
    message_liste[index_message] = message;
    index_message = index_message + 1;
  }
}

/// @brief Remplit chaine_texte avec les données du message présentées en ascii
/// @param message structure de transfert entre les cartes
/// @param chaine_texte doit être allouée, prévoir  64 octets. Attention ce ne sera pas suffisant dans tous les cas
/// @return 0 si tout s'est bien passé, 1 sinon
char message_to_string(struct message_t message, char * chaine_texte){
  if(message.type == 'r' || message.type == 'w' || message.type == 'd'){
    if(message.type == 'd' || message.type == 'w' ){
      sprintf(chaine_texte, "%c: registre: %d, id_carte: %d, taille: %d", message.type, message.id_carte, message.taille_donnees);
    }else if(message.type == 'r'){
      sprintf(chaine_texte, "%c: registre: %d, taille: %d", message.type, message.adresse_registre, message.taille_donnees);
    }else{
      return 1;
    }

    if(message.type == 'r' || message.type == 'w' ){
      char value[5];
      strcat(chaine_texte, ", données: ");
      for(int i=0; i< message.taille_donnees; i++){
        sprintf(value, "%d ", message.donnees[i]);
        strcat(chaine_texte, value);
      }
    }

    strcat(chaine_texte, "\n");
    return 0;
  }
  if(message.type == '>'){
    chaine_texte[0] = '>';
    chaine_texte[1] = '\0';
    strcat(chaine_texte, message.donnees);
    strcat(chaine_texte, "\n");
    return 0;
  }
  return 1;

}


struct message_t messagerie_read_message(const char * chaine, unsigned int * position_chaine){
    struct message_t message;
    unsigned int position_sous_chaine;
    message.type = 0;

    switch(chaine[*position_chaine]){
        case '>':
          // copier les données tant qu'on ne trouve pas un retour à la ligne ou de fin de chaine
          position_sous_chaine = 0;
          message.type = '>';
          while(*position_chaine + position_sous_chaine < 1024 && position_sous_chaine < 254){
            message.donnees[position_sous_chaine] = chaine[*position_chaine + position_sous_chaine];
            
            if(message.donnees[position_sous_chaine] == '\n' || message.donnees[position_sous_chaine] == '\0'){
              break;
            }
            position_sous_chaine++;
          }
          if(message.donnees[position_sous_chaine-1] != '\0'){
            message.donnees[position_sous_chaine] == '\0';
          }
          *position_chaine = *position_chaine + position_sous_chaine;
          break;

        case 'd':
          if(*position_chaine + 4 < 1024){
            if(chaine[*position_chaine + 4] == '\0'){
              message.type = chaine[*position_chaine];
              message.id_carte = chaine[*position_chaine + 1];
              message.adresse_registre = chaine[*position_chaine + 2];
              message.taille_donnees = chaine[*position_chaine + 3]; 
            }
          
          }

        case 'r':
          if(*position_chaine + 2 < 1024){
            // Read size
            message.taille_donnees = chaine[*position_chaine + 2];
            position_sous_chaine = 2 + message.taille_donnees + 1;
            if(*position_chaine + position_sous_chaine < 1024){
              if(chaine[*position_chaine + position_sous_chaine] == '\0'){
                message.type = chaine[*position_chaine];
                message.adresse_registre = chaine[*position_chaine + 1];
                message.taille_donnees = chaine[*position_chaine + 2]; // déjà fait plus haut
                memcpy(message.donnees, &(chaine[*position_chaine + 3]), message.taille_donnees); 
              }
            }
          }
          break;
          
        case 'w':
          if(*position_chaine + 3 < 1024){
            // Read size
            message.taille_donnees = chaine[*position_chaine + 3];
            position_sous_chaine = 3 + message.taille_donnees + 1;
            if(*position_chaine + position_sous_chaine < 1024){
              if(chaine[*position_chaine + position_sous_chaine] == '\0'){
                message.type = chaine[*position_chaine];
                message.id_carte = chaine[*position_chaine + 1];
                message.adresse_registre = chaine[*position_chaine + 2];
                message.taille_donnees = chaine[*position_chaine + 3]; // déjà fait plus haut
                memcpy(message.donnees, &(chaine[*position_chaine + 4]), message.taille_donnees); 
              }
            }
          }
        default:
      }
}