#include <stdio.h>
#include <string.h>
#include "aes.h"
//#include "crc.h"

#define MAX_LENGH	(2 * 1024 * 1024) // muss durch 16 teilbar. Da AES auf 16Bit Buffer eingestellt, eventuell änderbar

#define MAX_PATH	255

uint8_t input[MAX_LENGH];
uint8_t output[MAX_LENGH];

uint8_t key[16] = { 0x5c, 0x38, 0x36, 0x57, 0x60, 0x3d, 0x0e, 0x38, 0x61, 0x1e, 0x4e, 0x21, 0x62, 0x19, 0x47, 0x62 };

int main(int argc, char *argv[])
{

	int i=0;
	FILE *fp= NULL;
	int c=0;
	int filePos=0;
	uint32_t fileSize=0;
	char outputFilename[MAX_PATH] = "";
	//uint16_t crc=0;

	//uint16_t hw_id;
	//uint16_t fw_major;
	//uint16_t fw_minor;
	//uint16_t fw_build;

	printf("Starting file %s.\n", argv[0]);

	memset(input,0xFF,MAX_LENGH);
	memset(output,0xFF,MAX_LENGH);

	if (argc < 2)
	{
		printf("Was soll ich den verschluesseln?\nDu hast vergessen einen Dateinahmen anzugeben!\n");
		printf("Bitte gib es z.B. so ein: FileEncrypt abc.bin\n");
		printf("LG Falko\n");
		return 0;
	}

	//printf ("Bitte geben Sie die Hardware ID ein: ");
	//scanf ("%hu", &hw_id);

	//printf ("Bitte geben Sie die Firmware Version  ein, Major: ");
	//scanf ("%hu", &fw_major);

	//printf ("Bitte geben Sie die Firmware Version  ein, Minor: ");
	//scanf ("%hu", &fw_minor);

	//printf ("Bitte geben Sie die Firmware Version  ein, Build: ");
	//scanf ("%hu", &fw_build);


	// oeffnen im Lesemodus
	fp = fopen(argv[1], "rb");

	if(fp == NULL)
	{
		printf("Cannot open firmware file %s!\n", argv[1]);
		fflush(stdout);
		return -1;
	}

	 printf("Loading file %s\n", argv[1]);
	 fflush(stdout);
    do
    {
      c = fgetc (fp);
      if (c == EOF) break;
      input[filePos] = c;
      //crc= update_crc_16(crc, c );
      filePos++;
      if (filePos > (MAX_LENGH-1))
      {
  		printf("Datei zu groß für aktuellen Buffer\n");fflush(stdout);
  		return -2;
      }

    } while (1);


    fclose (fp);

    fileSize = filePos;


    // --- ENDE DATEI EINLESEN ----


    fflush(stdout);

    // print the resulting cipher as 4 x 16 byte strings
    printf("Encrypting file...\n");
    fflush(stdout);

    for(i = 0; i <  (MAX_LENGH / 16); ++i)
    {
        AES128_ECB_encrypt(input + (i*16), key, output+(i*16));
    }

    //Datei schreiben - verschlüsselt
	//oeffnen im schreibmodus, binär
    //strcat (outputFilename, "encrypted_");
    strcat(outputFilename, argv[1]);
    // Let's find last '/' or '\' in path
    char* fn = NULL;
    if (!((fn = strrchr(outputFilename, '/')) || (fn = strrchr(outputFilename, '\\'))))
	{
    	printf("Cannot find filename in %s", argv[1]);
    	return -4;
    }
    // Moving pointer to the beginning of the real file name
    fn++;
    char filename[MAX_PATH] = "";
    strcpy(filename, fn);
    char dir[MAX_PATH] = "";
    strncat(dir, outputFilename, fn - outputFilename);
    char new_filename[255] = "";
    strcpy(new_filename, "encrypted_");
    strcat(new_filename, filename);
    strcat(dir, new_filename);

    printf("Writing file %s\n", dir);
    fflush(stdout);

	fp = fopen(dir, "wb");

	if(fp == NULL)
	{
		printf("File %s cannot be written!\n", dir);
		return -3;
	}

	filePos=0;
    do
    {
      c = output[filePos];
      fputc (c, fp);
      filePos++;
    } while (filePos < fileSize);
    fclose (fp);


    printf ("Bootloader file generated!\n");
    printf ("Bin file size:\t\t\t\t %d\n", fileSize);
    //printf ("HW Id:\t\t\t\t\t %d\n", hw_id );
    //printf ("FW Version:\t\t\t\t %d.%d.%d\n", fw_major, fw_minor, fw_build );
    printf ("Used Key for AES 128 Bit encryption:\t ");
    phex(key,15);
    //printf ("Calculated CRC:\t\t\t\t %x\n", crc);
    printf("Finished!\n");
    fflush(stdout);

	return 0;
}
