// server 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>

typedef struct {
	char product[20];
	int price;
} List;

long pid;
char *shmaddr;
FILE *fp;
int mesid;
int shmid;
int sfile=1;

struct {
	long mestype;
	long mes;
} messagefrom;

void hndler(int s)
{
	int i;
	if (pid) {
		kill((int) pid,SIGKILL);
		printf("The process %d is stopping...\n", (int) pid);
	}
	long pd[4];
	pd[0]=0;pd[1]=0;pd[2]=0;pd[3]=0; 
	while(msgrcv(mesid, &messagefrom, sizeof(messagefrom),0,IPC_NOWAIT)!=-1){
		sleep(0.5);
		if (messagefrom.mestype==1){
			int b=1;
			for (i=0;i<4;i++) 
				if (pd[i]==messagefrom.mes)
					b=0;
			if (b) {
				kill((int) messagefrom.mes, SIGKILL);
				printf("The client %d is stopping...\n", (int) messagefrom.mes);
			}
			for (i=0;i<4;i++) 
				if (pd[i]==0){
					pd[i]=messagefrom.mes;
					break;
				}
		}
	}
	msgctl (mesid, IPC_RMID, 0);
	
	if (sfile==1) 
		fp=fopen("DATABASE5.txt","wb");
	
	i = 0;
	while (shmaddr[i]!=EOF) fputc(shmaddr[i++],fp);
	
	fclose(fp);	

	shmctl(shmid,IPC_RMID,NULL); 
	exit(0);
	printf("server stopes to work...\n");
	
	exit(EXIT_SUCCESS);
}

void sort(void)
{	
	int i=0,j=0;
	int *p;
	List *base;
	char *s;

	base = (List*) malloc(100*sizeof(List));
	while (shmaddr[i]!=EOF) {
		s=shmaddr+i;
		int k=0;
		while ((base[j].product[k]=s[k])!='\0' && k < 20 ) 
			++k;
		s=s+20;
		p = (int*) s;
		base[j].price= *p;
		i=i+20+sizeof(int);
		j++;
	}
	int n=j;
	{
		int i,j,l,r,m; List x;
		for (i=1; i<n; i++)
		{
			x=base[i]; l=0; r=i-1;
			while(l<=r){
				m=(l+r)/2;
				if (x.price<base[m].price) r=m-1;
				else l=m+1;
			}
			for (j=i-1; j>=l; --j)
				base[j+1]=base[j];
			base[l]=x;
			
		}
	}
	for (i=0;i<j; i++)
		printf("product: %s price: %d\n", base[i].product, base[i].price);
	printf("\n");
	s =(char*) base;
	j=j*sizeof(List);
	for (i=0; i<j; i++)
		shmaddr[i]=s[i];
	shmaddr[i]=EOF;

}


int main(int argc, char **argv)
{
	key_t key_message;

	key_t key_storage;

	struct {
		long mestype;
		long mes;
	} messageto;
	
	key_message = ftok("queuemessage",'r');
	mesid = msgget(key_message, 0666|IPC_CREAT);

	key_storage = ftok("/tmp/ter",'S');
	shmid = shmget(key_storage, 100*(20+sizeof(int)), 0666|IPC_CREAT);
	shmaddr = shmat(shmid,NULL,0);
	//printf ("%u\n", shmaddr);
	int i = 0;
	
	if(!(fp = fopen("DATABASE5.txt","rb"))) {
		fp = fopen("DATABASE5.txt","wb"); 
		sfile=0;
		shmaddr[0]=EOF;
	}
	else {
		i = 0;
		while((shmaddr[i++] = (char) fgetc(fp))!=EOF);
		fclose(fp);
	}
	signal(SIGINT,hndler);
	//printf("%d\n", --i);
	while(1){	
		int w;
		while(msgrcv(mesid, &messagefrom, sizeof(messagefrom), 1, 0)<0); 
		//printf("%d\n", w);
		messageto.mestype = messagefrom.mes;
		
		messageto.mes = 1;
		pid=messagefrom.mes;
		msgsnd (mesid, &messageto, sizeof(messageto), 0);
		
		
		step: ;	
		while(msgrcv(mesid, &messagefrom, sizeof(messagefrom),1, 0)<0);
		
		if (messagefrom.mes!=pid){
		msgsnd(mesid, &messagefrom, sizeof(messagefrom),0);
		goto step;
		}
		sort();   
  
		
	}
	
	return 0;
}


