/**
 * @file file_integrity_check.c
 *
 * @brief This file contains functions that provides demonstration of
 *        usage of file integrity check APIs
 *
 * The functions provided in the file provides demonstration on
 * usage of file integrity APIs
 */
#include "file_integrity_check.h"

#include "stdio.h"

#include "common.h"

uint32_t Crc32(uint32_t Crc, uint32_t Data)
{
	uint8_t index;

	Crc = Crc ^ Data;
	for (index = 0; index < 32; index++)
	{
		if (Crc & 0x80000000)
		{
			Crc = (Crc << 1) ^ 0x04C11DB7;	// Polynomial used in STM32
		}
		else
		{
			Crc = (Crc << 1);
		}
	}

	return (Crc);
}


uint32_t calc_checksum_bulkdata(uint8_t *data_buf,uint32_t length)
{
	uint32_t read_buffer = 0xffffffff;
	uint32_t calc_CRC;
	uint32_t buf_inc;

	// checking if the file exist or not
	if (data_buf == NULL)
	{
		printf("INTG | Buffer ptr Null  !\n");
		return 0;
	}
	buf_inc = 0;
	calc_CRC = 0xFFFFFFFF;
	while (length > 3)
	{
		memcpy(&read_buffer,&data_buf[buf_inc],4);
		calc_CRC = Crc32(calc_CRC, read_buffer);
		length -= 4;
		buf_inc +=4;
	}

	return calc_CRC;
}


#ifndef FT_OBC

long int findSize(char file_name[])
{
	// opening the file in read mode
	FILE *fp = fopen(file_name, "r");

	// checking if the file exist or not
	if (fp == NULL)
	{
		printf("SIZE | File opening error %s !\n",file_name);
		return -1;
	}

	fseek(fp, 0L, SEEK_END);

	// calculating the size of the file
	long int res = ftell(fp);

	// closing the file
	fclose(fp);

	return res;
}




uint32_t calc_checksum(char file_name[], uint32_t length)
{
	uint32_t read_buffer = 0xffffffff;
	uint32_t calc_CRC;
	// opening the file in read mode
	FILE *fp = fopen(file_name, "r");

	// checking if the file exist or not
	if (fp == NULL)
	{
		printf("INTG | File opening error %s !\n",file_name);
		return 0;
	}

	calc_CRC = 0xFFFFFFFF;
	while (length > 3)
	{
		fread(&read_buffer, 4, 1, fp);
		calc_CRC = Crc32(calc_CRC, read_buffer);
		length -= 4;
	}

	// closing the file
	fclose(fp);
	return calc_CRC;
}

uint32_t file_integrity_check(char file_name[])
{
	long int file_size;
	uint32_t checksum;
	file_size = findSize(file_name);
	if (file_size != -1)
	{
		printf("INTG | File Size %ld !\n",file_size);
		checksum = calc_checksum(file_name, file_size);
	}
	else
	{
		checksum = 0;
	}

	return checksum;
}


#endif
