#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF 200
#define RECORDS 50
#define SPACES 4

FILE * file1, * file2, *resultFile;

struct record {
	char ingr[BUF/2];
	char weight[BUF/2];
	char dv[BUF/2];
};

void parseFile(struct record * records, FILE * file);
void writeResultToFile(struct record * f1, struct record * f2);
void replace(char * str, char c, char r);
void reverse(char * str);
void crop(char * str, char c);
void trim(char * str);
void fillWeight(char * str, char * weight);
void fillDv(char * str, char * dv);

int main(int argc, char * argv[]) {
    if (argc != 3) {
		fprintf(stderr, "Usage: cmpr.exe F1 F2\n");
		exit(1);
	}
	char * fileName1 = argv[1];
    file1 = fopen(fileName1, "r");
    if (file1 == NULL) {
        fprintf(stderr, "Can't open input file %s!\n", file1);
        exit(1);
    }
	char * fileName2 = argv[2];
    file2 = fopen(fileName2, "r");
    if (file2 == NULL) {
        fprintf(stderr, "Can't open input file %s!\n", file2);
        exit(1);
    }
	char * resultFileName = fileName1;
	strcat(resultFileName, "_");
	strcat(resultFileName, fileName2);
	strcat(resultFileName, "_DIFF.txt");
	resultFile = fopen(resultFileName, "w");
	if (resultFile == NULL) {
        fprintf(stderr, "Can't open input file %s!\n", resultFile);
        exit(1);
    }
	
	struct record fOneRecs		[RECORDS];
	struct record fTwoRecs		[RECORDS];
	
    parseFile(fOneRecs, file1);
	parseFile(fTwoRecs, file2);
	writeResultToFile(fOneRecs, fTwoRecs);
    
    fclose(file1);
    fclose(file2);
    fclose(resultFile);
    return 0;
}

void parseFile(struct record * records, FILE * file) {
    char line   [BUF];
    char ingr   [BUF];
    char params [BUF];
    char weight [BUF];
    char dv     [BUF];
	int recCount = 0;
    
    while (fgets(line, sizeof(line), file) != NULL) {
        replace(line, '\t', ' ');
        reverse(line);
        int i = 0, count = 0;
        while (line[i]) {
            params[i] = line[i];
            if (count == SPACES) {
                int j = 0;
                ++i;
                params[i] = '\0';
                while (line[i]) {
                    ingr[j++] = line[i++];
                }
                ingr[j] = '\0';
                break;
            }
            if (line[i] == ' ') {
                count++;
            }
            ++i;
        }
        reverse(ingr);
        crop(ingr, '(');
        fillDv(params, dv);
        reverse(dv);
        reverse(params);
        trim(ingr);
        trim(params);
        fillWeight(params, weight);
		strcpy(records[recCount].ingr, ingr);
		strcpy(records[recCount].weight, weight);
		strcpy(records[recCount].dv, dv);
		recCount++;
    }
}

void writeResultToFile(struct record * f1, struct record * f2) {
	int i = 0, j = 0, k = 0;
	while (1) {
		j = 0;
		if (!strcmp(f1[i].ingr, "")) break;
		while (1) {
			if (!strcmp(f2[j].ingr, "")) break;
			if (!strcmp(f1[i].ingr, f2[j].ingr)) {
				fprintf(resultFile, "%-20s %-10s(%-7sDV) \t%-5s %-10s(%-7sDV)\n", f1[i].ingr, f1[i].weight, f1[i].dv, "<>", f2[j].weight, f2[j].dv);
				k++;
			}
			j++;
		}
		i++;
	}
}


void replace(char *str, char c, char r) {
    while (*str) {
        if (*str == c) {
            *str = r;
        }
        ++str;
    }

}

void reverse(char * str) {
    char buffer[BUF];
    int i = strlen(str) - 1;
    int j = 0;
    for (i; i >= 0; i--) {
        buffer[j++] = *(str + i);
    }
    for (i = 0; i < strlen(str); i++) {
        *(str + i) = buffer[i];
    }
    *(str + i) = '\0';
}

void crop(char * str, char c) {
    while (*str) {
        if (*str == c) {
            *str = '\0';
            break;
        }
        str++;
    }
}

void trim(char * str) {
    char * end = str + strlen(str) - 1;
    if (*end == ' ') {
        *end = '\0';
    }
}

void fillWeight(char * str, char * weight) {
    int spaceCount = 0;
    while (*str == ' ' || *str == '\t') {
        ++str;
    }
    while (*str) {
        if (*str == ' ' || *str == '\t') ++spaceCount;
        if (spaceCount == 2) break;
        *weight++ = *str++;
    }
    *weight = '\0';
}
void fillDv(char * str, char * dv) {
    int spaceCount = 0;
    while(*str != ' ' && *str != '\t') {
        if (*str == '\n') {
            ++str;
            continue;
        }
        *dv++ = *str++;
    }
    *dv = '\0';
}
