#include <stdio.h>
#include <stdlib.h>
#include <gcrypt.h>
#include <sys/time.h>
#include <string.h>

int main(int argc, char **argv){
    if(argc != 2){
        printf("Syntax Error!\n");
        exit(1);
    }
	//printf("argc: %d\n", argc);
	//printf("argv[1] len: %lu argv[1] str: %s\n", strlen(argv[1]), argv[1] );
	FILE *fp;
//	return 0;

    char *filename = malloc(strlen(argv[1]) + 1);
    (void)strcpy(filename, (const char *)argv[1]);
    if( !(fp = fopen(filename, "rb")) ){
        printf("error opening ""%s""\n", filename);
        free(filename);
        exit(1);
    }

    fseek(fp , 0 , SEEK_END);
    size_t file_size = ftell(fp);
    rewind(fp);
	double time1 = 0;
	struct timeval starttime, endtime;
	gcry_error_t error_val;
	size_t length;
	void *digest;
	//GCRY_MD_SHA256  = 8
	int algo = GCRY_MD_SHA256;
	//size_t buf_length = strlen(argv[1]);
//	char *myword;
//	int counter1;

//	myword = malloc(sizeof(char)*buf_length);
//	strcpy(myword, argv[1]);

	//const void *buffer = 
	void *file_contents = malloc(file_size);
	size_t bytes_read = fread( (void *)file_contents, 1, file_size, fp );
	const void *buffer = file_contents;

	if(bytes_read != file_size){
		printf("Error: read %zubytes expected %zu\n", bytes_read, file_size);
		free(file_contents);
		free(filename);
		exit(1);
	}

	//printf("test\n");
	//const char GCRYPT_VERSION = 140;

       /* Version check should be the very first call because it
          makes sure that important subsystems are intialized. */
       if (!gcry_check_version (GCRYPT_VERSION))
         {
           fputs ("libgcrypt version mismatch\n", stderr);
           exit (2);
         }
     
       /* Disable secure memory.  */
       gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
     
       /* ... If required, other initialization goes here.  */
     
       /* Tell Libgcrypt that initialization has completed. */
       gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);

	//printf("done\n");

	//create context
	//gcry_error_t gcry_md_open (gcry_md_hd_t *hd, int algo, unsigned int flags)

gettimeofday(&starttime, NULL);
	//get length for message digest
	length = gcry_md_get_algo_dlen(algo);
	digest = malloc(sizeof(char)*length);

	//calculate message digest
	gcry_md_hash_buffer(algo, digest, buffer, file_size);

gettimeofday(&endtime, NULL);
time1 = ((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
printf("sha256 %lfbytes/sec\n", (double)file_size/time1);

	printf("sha256: %s\n", (char *)digest);


	fclose(fp);
	free(filename);
	free(file_contents);
	free(digest);
	return 1;
}
