/*
Dans ce fichier on trouvera les fonctions associées à la génération d'un password ayant les caractéristiques suivantes:
- longueur aléatoire entre 8 et 20 caractères
- caractères possibles: a-z; A-Z; 0-9.


*/

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

/*
Création et renommage de la structure Connexion servant à stocker un login et le mot de passe correspondant
*/
typedef struct
{
 char login[21];
 int password[21]; //le password est un tableau d'entiers, voir les fonctions de génération du mot de passe, et on le fait de taille maximale 20
} Connexion;


//le commentaire suivant contient les fonctions relatives à la partie 'liste chaînée' du TP que je n'ai pas
//eu le temps d'intégrer dans le main. Amusez-vous avec si vous voulez.

/*
typedef struct ElemConn ElemConn;

struct ElemConn
{
    Connexion Conn;
    ElemConn *suivant;
};

typedef struct
{
    ElemConn *premier;
} Liste;



Liste* initialisation()
{
    Liste* liste = malloc(sizeof(liste));
    ElemConn* element = malloc(sizeof(element));

    if(liste==NULL || element==NULL)
    {
        exit(0);
    }

    element->suivant=NULL;
    liste->premier=element;

    return liste;
}

void insertion(Liste* liste, int nvnombre)
{
    ElemConn* nouveau=malloc(sizeof(nouveau));
    int int_taille, int_compteur;
    if(liste==NULL||nouveau==NULL)
    {
        exit(0);
    }
    printf("Rentrez le login:\n");
    scanf("%s", nouveau->Conn.login);
        printf("Je vais vous generer un mot de passe. \n");
    int_taille = genererTaillePassword(); //on donne un taille aléatoire à notre mot de passe.

    for(int_compteur=1; int_compteur<=int_taille; int_compteur++) //connaissant la taille, on fait une boucle correspondante
    {
        nouveau->Conn.password[int_compteur - 1] = genererCaractereAlea(); //on remplit progressivement un tableau avec les valeurs générées
    }

    nouveau->suivant=liste->premier;
    liste->premier= nouveau;
}

void suppression(Liste* liste)
{
    if(liste==NULL)
    {
        printf("Suppression impossible");
    }
    if(liste->premier!=NULL)
    {
        ElemConn* aSupprimer=liste->premier;
        liste->premier=liste->premier->suivant;
        free(aSupprimer);

    }
}

void afficherListeChainee(Liste* liste)
{
    if (liste==NULL)
    {
        printf("Erreur.");
    }

    ElemConn* actuel =liste->premier;
    while(actuel!=NULL)
    {
        printf("Login:\t\t%s", actuel->Conn.login);
        afficherPassword( actuel->Conn.password, 21);
        actuel=actuel->suivant;
    }
}


Fonctions concernant la liste chainée, qui ne marchent pas toutes car non incluses dans le main faute de temps.ç


*/





int genererCaractereAlea() //cette fonction a pour but de générer le code ASCII 7 correspondant à un des
//caractères demandés de manière aléatoire.
{
    int int_charType, int_char;


    int_charType = rand()%3 +1; //création d'un choix aléatoire entre les trois types de caractère: minuscule, majuscule, chiffre.

    switch(int_charType) //en fonction du type choisi précédemment, on rentre dans différents cas.
    {
        case 1: //le type est un chiffre.
        int_char = rand()%10 + 48; //on génère un caractère en code ASCII 7 correspondant au type recherché.
        break;
        case 2: //le type est une lettre majuscule.
        int_char =rand()%26 + 65; //idem.
        break;
        case 3: //le type est une lettre minuscule.
        int_char = rand()%26 +97; //idem.
        break;

    }

    return int_char; //la fonction renvoie le code ASCII 7 du caractère généré aléatoirement.

}

int genererTaillePassword() //cette fonction très simple renvoie la taille du password comprise entre 8 et 20.
{
    int int_taille;
    srand(time(NULL));
    int_taille = rand()%12 + 8; //on génère une taille entre 8 et 20 aléatoirement.

    return int_taille; //on retourne la taille générée.
}

void afficherPassword(int *int_password, int int_taille) /*Le mot de passe généré ayant été stocké dans un tableau, on
affiche ce tableau. On notera que l'on ne met pas le tableau en paramètre mais bien le pointeur correspondant.*/
{
    int int_compteur;
    printf("\t\t"); //pour la clarté de la console :)
    for(int_compteur=0; int_compteur<int_taille; int_compteur++) //boucle d'affichage, qui s'arrête au bon moment
    {
        printf("%c", int_password[int_compteur]); /*affichage du caractère dont le code ASCII 7 a été stocké dans le case
        du tableau à laquelle on s'intéresse. le %c permet d'afficher le caractère et non le nombre. */
    }
    printf("\n"); //pour la magnificence de la console

}


void remplirConnexion()
{
    Connexion Conn;
    int int_taille, int_compteur;

    printf("Rentrez votre login:\n");
    scanf("%s", Conn.login);
    printf("Je vais vous generer un mot de passe. \n");
    int_taille = genererTaillePassword(); //on donne un taille aléatoire à notre mot de passe.

    for(int_compteur=1; int_compteur<=int_taille; int_compteur++) //connaissant la taille, on fait une boucle correspondante
    {
        Conn.password[int_compteur - 1] = genererCaractereAlea(); //on remplit progressivement un tableau avec les valeurs générées
    }

    printf("Voici vos informations de connexion:\n\n");
    printf("\tLogin: \t\t\t%s\n\tPassword:", Conn.login);
    afficherPassword( &Conn.password, int_taille); //la fonction affiche le mot de passe.

}



void genererPassword() //cette fonction utilise les précédentes pour effectivement générer le mot de passe.
{
    int int_taille, int_compteur, int_choix, i; //déclaration des variables.
    int int_password[21];//on stockera le mot de passe dans un tableau de taille maximale 21.
    FILE* fichier=NULL; //Création d'un pointeur fichier (nom de la structure FILE en majuscule, merci les créateurs des stdio.lib) et
    //initialisation à NULL.
    srand(time(NULL)); //initialisation de la fonction rand.

    /*
    UN PETIT NB SUR LA FONCTION srand:

    Le srand initialise le calcul des valeurs aléatoires. En effet, l'ordinateur ne connaît pas le hasard,
    donc il le calcule.

    Si l'on avait mis la fonction srand dans la fonction genererCaractereAlea(), on aurait
    obtenu des mots de passes constitués uniquement d'un caractère (si si je vous jure, essayez!).

    */

    printf("Je vais vous generer un mot de passe. \n");
    int_taille = genererTaillePassword(); //on donne un taille aléatoire à notre mot de passe.

    for(int_compteur=1; int_compteur<=int_taille; int_compteur++) //connaissant la taille, on fait une boucle correspondante
    {
        int_password[int_compteur - 1] = genererCaractereAlea(); //on remplit progressivement un tableau avec les valeurs générées
    }


    do //boucle d'affichage des options concernant la sauvegarde du password
    {
    printf("\nVoulez-vous:\n1. Afficher le password?\n2. Enregistrer le password dans un fichier txt?\n3. Retourner au menu principal?\n");
    scanf("%d", &int_choix); //on demande à l'utilisateur ce qu'il faut faire avec les password généré.

    switch(int_choix) //en fonction du choix on fait différentes choses
    {
        case 1: //choix 1: affichage du password
        printf("\nLe mot de passe genere est le suivant: \n\n");
        afficherPassword( &int_password, int_taille); //la fonction affiche le mot de passe.

        /*
        NB: ici, on envoie à la fonction le pointeur correspondant au tableau contenant le mot de passe, et non le tableau lui-même
        Ceci permet de s'affranchir de la taille du tableau lorsqu'on le passe en paramètre. C'est assez stylé.
        */
        break;

        case 2: //choix 2: on rentre le mot de passe dans le fichier resultat.txt

        fichier = fopen("resultat.txt", "w+"); //ouverture du fichier en mode lecture et écriture avec suppression du contenu
        //au préalable

        if (fichier != NULL) //on teste si le fichier est bien ouvert
        {
            for(i=0; i<int_taille; i++) //boucle qui rentre les caractères un par un dans le fichier
            {
                fputc(int_password[i], fichier); //sauvegarde du caractère numéro i+1 dans le fichier
            }
            printf("\n J'ai ecrit un nouveau mot de passe dans le fichier resultat.txt.\n");
            //on dit à l'utilisateur qu'on a écrit dans le fichier
            fclose(fichier); //on ferme le fichier pour libérer de la mémoire
        }
        else{printf("\nErreur lors de l'ouverture du fichier.\n");}


        case 3: break; //cas de sortie

        default: printf("\nMauvais choix, recommencez.\n"); //cas de choix invalide
        break;
    }
    }while(int_choix!=3); //condition de sortie de boucle

}


