/**
 *--------------------------------------------------------------------\n
 *          HSLU T&A Hochschule Luzern Technik+Architektur            \n
 *--------------------------------------------------------------------\n
 *
 * \brief         n size number computation - ASYD
 * \file
 * \author        Stefano Nicora, stefano.nicora@hslu.ch
 * \date          07.03.2022
 *
 *--------------------------------------------------------------------
 */

#ifndef _ENCRYPTIONARITHMETIC_H_
#define _ENCRYPTIONARITHMETIC_H_

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

typedef struct encryptArithmetic {
	bool hasOverflown;		/* whether or not the computation has generated a overflow */
	bool memAllocSuccess;	/* whether or not the calloc call has been successful */
	bool compSuccess;		/* whether or not the desired computation has been successful */
	uint32_t remainder;		/* holds the remainder(if available) of the division */
	uint32_t* number;		/* holds the address of the computed number */
}t_encryptionArithmetic;

typedef enum {
	ADD,
	SUB,
	DIV,
	MUL,
	AND,
	OR,
	XOR
}t_operation;

/* Computes the result of two numbers while specifying the operation with an OPCODE
 *
 * Usage:
 * Arrays with uint32_t sized entries (number1 and number2) hold the wanted values which get computed bitwise
 * from LSB to MSB starting at index 0. Data gets stored as "little Endian".
 * array[0] = [X X X X X X X X X]
 * 	  		 MSB			   LSB
 * */
t_encryptionArithmetic* encryptionArithmetic(uint32_t* number1, uint32_t* number2, t_encryptionArithmetic* result, uint16_t size, t_operation OPCODE);

/* initialize the module */
t_encryptionArithmetic* encryptionArithmetic_Init(t_encryptionArithmetic* result, uint16_t size);

/* deinitialize the module and free the allocated no longer needed memory */
void encryptionArithmetic_DeInit(t_encryptionArithmetic* ptr);

/* returns the number of bits representing the number */
uint16_t encryptionArithmetic_numberSize(uint32_t* number, uint16_t size);

/* returns true if first number is larger than the second one */
bool encryptionArithmetic_isLarger(uint32_t* number1, uint32_t* number2, uint16_t size);

/* 
turns a number in a string-format in hex into a regular number inside the library 
returns true if successful 
*/
bool encryptionArithmetic_stringToHex(char* src, uint32_t* dest, uint16_t length);

void encryptionArithmetic_copyNumber(uint32_t* src, uint32_t* dest, uint16_t length);
#endif /* _ENCRYPTIONARITHMETIC_H_ */
