#include "issue.h"
//#include <stdio.h>

int ie_setup(issuer_master_key_t *master_key)
{
    FILE *fp;
    int r;
    char gen = 'y';

  /* if( access( "/tmp/hello-world-pc/master.txt", F_OK ) == 0 ){
        printf("Soubor s Master klíčem již existuje, přejete si ho přepsat?[y/n]: ");
        scanf(" %c",&gen);
    }
    else{
        gen = '^';
    }*/

    if (gen == 'y' || gen == '^') {

        if (master_key == NULL) {
            return -1;
        }

        // random master key
        r = RAND_bytes(master_key->sk, 16);
        if (r != 1) {
            return -1;
        }

        fp = fopen("/tmp/hello-world-pc/master.txt", "w");

        for (int i = 0; i < sizeof(master_key->sk) - 1; i++) {
            fprintf(fp, "%u ", master_key->sk[i]);
        }
        fprintf(fp, "%u", master_key->sk[AES_BLOCK_SIZE - 1]);

        fclose(fp);

        if(gen == 'y') {
            printf("soubor s master klíčem byl přepsán");
        } else{
            printf("soubor s master klíčem byl vygenerován");
        }
    }

   /* FILE *myFile;
    myFile = fopen("/tmp/hello-world-pc/master.txt", "r");

    //read file into array
    uint8_t numberArray[AES_BLOCK_SIZE + 1];
    int i;

    if (myFile == NULL){
        printf("Error Reading File\n");
        exit (0);
    }

    for (i = 0; i < 16; i++){
        fscanf(myFile, "%u ", &numberArray[i] );
    }

    for (i = 0; i < 16; i++){
        printf("%u ", numberArray[i]);
    }

    fclose(myFile);*/

    return 0;
}

int ie_issue_U(user_identifier_t ue_identifier,user_private_key_t *ue_private_key)
{
    EVP_CIPHER_CTX *ctx;

    int length;
    int r;
    FILE *verifier;
    FILE *user;
    char gen = 'y';

  /*  if( access( "/tmp/hello-world-pc/user.txt", F_OK ) == 0 ){
        printf("Soubor s klíčem uživatele již existuje, přejete si ho přepsat?[y/n]: ");
        scanf(" %c",&gen);
        //printf("%c je tu", gen);
    }
    else{
        gen = '^';
    }*/

    if( gen == 'y' || gen == '^') {

        if (ue_private_key == NULL)
        {
            return -1;
        }
        // Create and initialise the context
        ctx = EVP_CIPHER_CTX_new();
        if (ctx == NULL) {
            return -2;
        }

        if( access( "/tmp/hello-world-pc/verifier.txt", F_OK ) != 0 ){
            printf("Soubor s verifier klíčem chybí!");
            return 0;
        }

        verifier = fopen("/tmp/hello-world-pc/verifier.txt", "r");

        //read file into array
        uint8_t verifier_key[AES_BLOCK_SIZE + 1];

        if (verifier == NULL){
            printf("Error Reading File\n");
            exit (0);
        }

        for (int i = 0; i < 16; i++){
            fscanf(verifier, "%u ", &verifier_key[i] );
        }

        fclose(verifier);

        /// user key derivation
        // initialise the encryption operation using the verifier secret key
        r = EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, verifier_key, NULL);
        if (r != 1) {
            return -7;
        }

        // disable padding
        EVP_CIPHER_CTX_set_padding(ctx, 0);

        // obtain the user private key using its identifier
        r = EVP_EncryptUpdate(ctx, ue_private_key->sk, &length, ue_identifier.buffer, ue_identifier.buffer_length);
        if (r != 1) {
            return -8;
        }
        assert(length == AES_BLOCK_SIZE); // no padding, data length is 128 bits

        // finalise the encryption
        r = EVP_EncryptFinal_ex(ctx, ue_private_key->sk, &length);
        if (r != 1) {
            return -9;
        }
        assert(length == 0); // no output expected, length must be 0

        ///write user key to file
        user = fopen("/tmp/hello-world-pc/user.txt", "w");

        for (int i = 0; i < sizeof(ue_private_key->sk) - 1; i++) {
            fprintf(user, "%u ", ue_private_key->sk[i]);
        }
        fprintf(user, "%u", ue_private_key->sk[AES_BLOCK_SIZE - 1]);

        fclose(user);

        EVP_CIPHER_CTX_free(ctx);

        if(gen == 'y') {
            printf("soubor s user klíčem byl přepsán");
        } else{
            printf("soubor s user klíčem byl vygenerován");
        }
    }


    return 0;
}
int ie_issue_M(verifier_identifier_t ve_identifier, verifier_private_key_t *ve_private_key)
{
    EVP_CIPHER_CTX *ctx;

    int length;
    int r;
    FILE *master;
    FILE *verifier;
    char gen = 'y';

   /*if( access( "/tmp/hello-world-pc/verifier.txt", F_OK ) == 0 ){
         printf("Soubor s klíčem ověřovatele již existuje, přejete si ho přepsat?[y/n]: ");
         scanf(" %c",&gen);
         //printf("%c je tu", gen);
     }
     else{
         gen = '^';
     }*/

    if( gen == 'y' || gen =='^') {

        if (ve_private_key == NULL) {
            return -1;
        }

        // Create and initialise the context
        ctx = EVP_CIPHER_CTX_new();
        if (ctx == NULL) {
            return -2;
        }

        if( access( "/tmp/hello-world-pc/master.txt", F_OK ) != 0 ){
            printf("Soubor s master klíčem chybí!");
            return 0;
        }

        master = fopen("/tmp/hello-world-pc/master.txt", "r");

        //read file into array
        uint8_t master_key[AES_BLOCK_SIZE + 1];

        if (master == NULL){
            printf("Error Reading File\n");
            exit (0);
        }

        for (int i = 0; i < 16; i++){
            fscanf(master, "%u ", &master_key[i] );
        }

        fclose(master);

        /// verifier key derivation
        // initialise the encryption operation using the issuer master key
        r = EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, master_key, NULL);
        if (r != 1) {
            return -4;
        }

        // disable padding
        EVP_CIPHER_CTX_set_padding(ctx, 0);

        // obtain the verifier private key using its identifier
        r = EVP_EncryptUpdate(ctx, ve_private_key->sk, &length, ve_identifier.buffer, ve_identifier.buffer_length);
        if (r != 1) {
            return -5;
        }
        assert(length == AES_BLOCK_SIZE); // no padding, data length is 128 bits

        // finalise the encryption
        r = EVP_EncryptFinal_ex(ctx, ve_private_key->sk, &length);
        if (r != 1) {
            return -6;
        }
        assert(length == 0); // no output expected, length must be 0

        ///write verifier key to file
        verifier = fopen("/tmp/hello-world-pc/verifier.txt", "w");

        for (int i = 0; i < sizeof(ve_private_key->sk) - 1; i++) {
            fprintf(verifier, "%u ", ve_private_key->sk[i]);
        }
        fprintf(verifier, "%u", ve_private_key->sk[AES_BLOCK_SIZE - 1]);

        fclose(verifier);

        EVP_CIPHER_CTX_free(ctx);

        if(gen == 'y') {
            printf("soubor s verifier klíčem byl přepsán");
        } else{
            printf("soubor s verifier klíčem byl vygenerován");
        }
    }

    return 0;
}