//client version 1.0;

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h> 

typedef struct {
	char product[20];
	int price;
} List;

char *shmaddr;


int correct(char *s, int n)
{
	int i=0,k=1;
	while (s[i]!='\0' && i < n && k)
		if (!isdigit(s[i++])) k=0;
	return k;
}

int strcmp1(char *s, char *ct)
{	
	int b=0;
	int i=0;
	while(s[i]!='\0'){
		if(s[i]!=ct[i]) {
			b=1;
			break;
		}
	++i;	
	} 
	if (!b)
		if (ct[i]!='\0') b=1;
	return b;
}

int product(char *s)
{
	int i=0;
	int b=0;
	while (s[i]!='\0'){
		if (s[i]!=' '){
			b=1;
			break;
		}
	++i;
	}
	return b;		
}

void Add(void)
{	
	int b=1;
	printf("Please write a product(less than 20 characters): \n");
	char *s;
	s=(char*) malloc(20*sizeof(char));
product:s=gets(s);
	if (!product(s)) {
		printf("Write not only the spaces!!\n");
		goto product;
	}	
	printf("Please write a product price: \n");
 price: ;
	char *tem;
	tem=(char*) malloc(20*sizeof(char));
	tem=gets(tem);
	if (correct(tem,20)) {
		int i;
		i=0;
		int N=0;
		while (b && shmaddr[i]!=EOF){
			char *sk;
			sk=shmaddr+i;
			if (!strcmp1(sk,s)) b=0;
			i=i+sizeof(List);
			++N;
		}
		if (b){
			if (N>=100){
				printf("IN DATABASE TOO MANY RECORDINGS, CAN NOT TO WRITE ANOTHER ONE!!!\n");
				goto end;
			}
		
			int k=0;
			while ((shmaddr[k+i]=s[k])!='\0' && k < 20 ) 
				++k;
		
			char *c;
			int *p;
			c=shmaddr + i + 20;
			p = (int*) c;
			*p=atoi(tem);
			shmaddr[i+sizeof(List)]=EOF;
		}
		else 
			printf("THE FIELD WITH SUCH PRODUCT EXISTING!! CAN NOT TO WRITE\n");
	} 
	else {
		printf("please write a correct price\n");
		goto price;
	}
end: ;
}

void Erase(void)
{
	int  b=0;
	
	printf("Please write a product(less than 20 characters): \n");
	char *s;
	s=(char*) malloc(20*sizeof(char));
	
product:s=gets(s);
	if (!product(s)){ 
		printf("Write not only the spaces!!\n");
		goto product;	
	}
	int i=0;
	
	while(!b && shmaddr[i]!=EOF) {
		char *tmp;
		tmp = shmaddr + i;
		if (!strcmp(tmp,s)) {
			b=1;
			break;
		}
		i=i+sizeof(List);
	}
	printf("%d\n", b);
	if (b==1){
		while (shmaddr[i+sizeof(List)]!=EOF){
			int j=0;
			for (j=0; j<sizeof(List); j++)
				shmaddr[j+i]=shmaddr[j+i+sizeof(List)];
			i=i+sizeof(List);
		}
		shmaddr[i]=EOF;
	}
	else
		printf("THE RECORDING WITH THE FOLLOWING KEY FIELD IS NOT EXISTING!!!\n");
}

void Change(void)
{
	int b=0;
	
	printf("Please write a product(less than 20 characters): \n");
	char *s;
	s=(char*) malloc(20*sizeof(char));
product:s=gets(s);
	if (!product(s)) {
		printf("Write not only the spaces!!\n");
		goto product;	
	}
	int i=0;
	
	while (!b && shmaddr[i]!=EOF){
		char *tmp;
		tmp = shmaddr + i;
		if (!strcmp1(tmp,s)) {
			b=1;
			break;
		}
		i=i+sizeof(List);
	}
	if (b==1){
		printf("Please write a new name of product: \n");
	product1:s=gets(s);
		if (!product(s)) {
			printf("Write not only the spaces!!\n"); 
			goto product1;	
		}
		int proverka=0;
		int j=0;
		while (shmaddr[j]!=EOF){
				char *tmp;
				tmp = shmaddr + j;
				if (!strcmp1(tmp,s)){
					++proverka;
					break;
				}
				j=j+sizeof(List);
			}
		if (proverka==1) {
			printf("IN DATABASE THERE IS A PRODUCT WITH SUCH NAME!!!\n");
			goto end;
		}
		int k=0;
		while ((shmaddr[k+i]=s[k])!='\0' && k < 20 ) 
			++k;
		
		printf("Please write a product price: \n");
price: ;	s=gets(s);
		if (correct(s,20)) {
			char *c;
			int *p;
			c=shmaddr + i + 20;
			p = (int*) c;
			*p=atoi(s);
		} 
		else {
			printf("please write a correct price\n");
			goto price;
		}

	}
	else
		printf("THE RECORDING WITH THE FOLLOWING KEY FIELD IS NOT EXISTING!!!\n");

end: ;
}

void Findkey(void)
{	
	int b=0;
	
	printf("Please write a product(less than 20 characters): \n");
	char *s;
	s=(char*) malloc(20*sizeof(char));
product:s=gets(s);
	if (!product(s)){ 
		printf("Write not only the spaces!!\n");
		goto product;	
	}
	int i=0;
	
	while (!b && shmaddr[i]!=EOF){
		char *tmp;
		tmp = shmaddr + i;
		if (!strcmp(tmp,s)) {
			b=1;
			break;
		}
		i=i+sizeof(List);
	}
	if (b==1){
		char *c;
		int *p;
		c=shmaddr + i + 20;
		p = (int*) c;
		printf("%d) product: %s price: %d\n", i/sizeof(List)+1, s, *p);
	}
	else
		printf("THE RECORDING WITH THE FOLLOWING KEY FIELD IS NOT EXISTING!!!\n");
}

void Findnkey(void)
{	
	int count = 0;

	printf("Please write a product price: \n");
price:	;
	char *temp;
	temp=(char*) malloc(20*sizeof(temp));
	temp=gets(temp);
	if (correct(temp,20)) {
		int i=0;
	
		while (shmaddr[i]!=EOF){
			char *c;
			int *p;
			int key=atoi(temp);
			c=shmaddr + i + 20;
			p = (int*) c;
			if (*p==key) {
				count++;
				char *tmp;
				tmp = shmaddr + i;
				printf("%d) product: %s price: %d\n", i/sizeof(List)+1, tmp, key);
			}
			i=i+sizeof(List);
		}
		if (!count) {
			printf("THERE IS NO PRODUCT WITH A FOLLOWING PRICE\n");	
		}
	}
	else {
		printf("please write a correct price\n");
		goto price;
	}

}

long pid;
int mesid;

struct {
	long mestype;
	long mes;
} messageto;


void handlr(int s)
{
	messageto.mestype = 1;
	messageto.mes=pid;
		
	 msgsnd (mesid, &messageto, sizeof(messageto), 0);
	exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
	key_t key_message;

	key_t key_storage;
	int shmid;

	struct {
		long mestype;
		long mes;
	} messagefrom;
	pid=getpid();
	key_message = ftok("queuemessage",'r');
	mesid = msgget(key_message, 0);   

	key_storage = ftok("/tmp/ter",'S');
	shmid = shmget(key_storage, 100*sizeof(List), 0666|IPC_CREAT);
	shmaddr = shmat(shmid,NULL,0);
	char *answer;
	
	answer=(char*) malloc(20*sizeof(char)); 
	
	signal(SIGINT,handlr);
	do {
		messageto.mestype = 1;
		messageto.mes = pid;

		msgsnd (mesid, &messageto, sizeof(messageto), 0); 
		
		while(msgrcv (mesid, &messagefrom, sizeof(messagefrom), pid, 0)<0);   
		
		printf("What kind of demand whould you like to choose?\n\n");
		printf("1) Add a new recording. write '1'\n");
		printf("2) Erase a certain recording with following key field. write '2'\n");
		printf("3) Change data in a string with following key field. write '3'\n");
		printf("4) Find a recording by  key field. write '4'\n");
		printf("5) Find a recording(recordings) by  nonkey field. write '5'\n\n");
		
		int demn;
		char *var;
		var = (char*)  malloc(20*sizeof(char)); 
	choose:	scanf("%s", var);
		if (!correct(var,20)) {
			printf("write a number!!!\n");
			goto choose;
		}
		char c;
		c=getchar();
		demn=atoi(var);
		switch (demn) {
			case 1: Add();		break;	
			case 2:	Erase();	break;	
			case 3:	Change();	break;	
			case 4:	Findkey();	break;	
			case 5:	Findnkey();	break;	
			default: printf("The value of demand is uncorrect, write a correct num \n"); goto choose;
		}
		
		
		
		messageto.mestype = 1;
		messageto.mes=pid;
		
		printf("another demands? yes or no?\n");
	
		scanf("%s", answer);


		msgsnd (mesid, &messageto, sizeof(messageto), 0);
	
		}while (!strcmp(answer,"yes"));
		
		
		return 0;
}





