//
// Created by miti on 2019-12-24.
//

#include "DeploymentStageLogic.h"
#include "stdio.h"
#include <errno.h>
#include <string.h>

// For socket programming
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>

// Sets up a socket connected to the port passed as input - returns the socket FD on success and -1 on error.
// Also prints the errno on error.
int DeploymentStageLogic::set_up_socket_connect(int port)
{
    int sock = 0;
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Error in socket call - errno is %d \n", errno); fflush(stdout);
        return -1;
    }

    struct sockaddr_in serv_addr;
    memset(&serv_addr, '0', sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);

    // Convert IPv4 and IPv6 addresses from text to binary form
    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
    {
        printf("\nError in inet_pton - errno is %d\n", errno); fflush(stdout);
        return -1;
    }

    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        printf("\nError in connect - errno is %d \n", errno); fflush(stdout);
        return -1;
    }

    return sock;
}

void DeploymentStageLogic::set_target_hash(uint8_t* given_hash)
{
    uint32_t counter;
    for(counter=0; counter<32; counter++)
        target_hash[counter] = given_hash[counter];
}

int DeploymentStageLogic::main_logic(int decryptor_fd)
{
    uint8_t key[16];
    uint32_t ret_status;

    // Conduct LA.
    ret_status = laInitiator.conduct_la(decryptor_fd);
    if(ret_status != 0)
    {
        printf("LA initiator returned an error: %d\n", ret_status);
        fflush(stdout);
        return ret_status;
    }
    /*
     *
      printf("\nSuccessful LA with port %d.\n", DECRYPTOR_PORT);
      fflush(stdout);
     */

    printf("Setting up fd for post LA messaging.\n"); fflush(stdout);
    // Use the same channel for post-LA messages as the one used above for LA messages.
    postLaMessaging.set_fd(decryptor_fd);

    // Use the symmetric key from LA to send messages for the rest of the deployment stage.
    printf("Retrieving key from LA inititator.\n "); fflush(stdout);
    laInitiator.get_la_symmetric_key(key);
    printf("Setting key for post LA messaging.\n "); fflush(stdout);
    postLaMessaging.set_la_symmetric_key(key);

    // Send the target's hash to the decryptor enclave.
    return postLaMessaging.send_secure_msg(target_hash, 32);
}


