#include <stdio.h>
#include "Coordinator.h"

void PrintLockArr(LockArr *Arr);

void CreateLock( Lock* lock, int nodeId, int lockId, float hpf)
{


#ifdef PRINT

    PrintInLogFile( " in func %f \n", hpf);

#endif

    lock->NodeId = nodeId;
    lock->LockId = lockId;
    (lock->MagicNum).hpf = hpf;
}

void CopyLock( Lock *lock1, Lock* lock2) {
    lock1->NodeId = lock2->NodeId;
    lock1->LockId = lock2->LockId;
    (lock1->MagicNum).hpf = (lock2->MagicNum).hpf;
}

void CopyMagicNum( MagicNumber * num1, MagicNumber* num2) {
    num1->hpf = num2->hpf;
}

LockArr* appendLockArr(LockArr  *lockArr1, LockArr *lockArr2) {
    int     i;
    int     j;
    int     k;
    LockArr *tmp;

    tmp = (LockArr*) malloc (sizeof ( LockArr));

#ifdef PRINT

    PrintInLogFile( " In appendLockArr() \n");

#endif

    PrintLockArr( lockArr2);
    PrintLockArr( lockArr1);

#ifdef PRINT

    PrintInLogFile( " ----------------------------- \n");

#endif

	if(lockArr1 != NULL) {
		if(lockArr1->LockArr_len == 0) {
			free(lockArr1);
			lockArr1 = NULL;
		}
	}
	
	if(lockArr2 != NULL) {
		if(lockArr2->LockArr_len == 0) {
			free(lockArr2);
			lockArr2 = NULL;
		}
	}
	
    PrintLockArr( lockArr1);
    if (lockArr1 == NULL) {
    	if (lockArr2 != NULL) {
        	tmp->LockArr_len = lockArr2->LockArr_len;
        	tmp->LockArr_val = (Lock *) malloc(tmp->LockArr_len * sizeof( Lock)); 
        	for( i = 0; i < lockArr2->LockArr_len; i++) {
            	CopyLock( &(tmp->LockArr_val[i]),
                    &(lockArr2->LockArr_val[i]));
        	}
        return tmp;
    	}

    	return NULL; 
    }

    if (lockArr2 == NULL) {
    if (lockArr1 != NULL) {
        tmp->LockArr_len = lockArr1->LockArr_len;
        tmp->LockArr_val = (Lock *) malloc(tmp->LockArr_len * sizeof( Lock)); 

        for( i = 0; i < lockArr1->LockArr_len; i++) {
            CopyLock( &(tmp->LockArr_val[i]),
                    &(lockArr1->LockArr_val[i]));
        }
        return tmp;
    }
    return NULL;
    }

    tmp->LockArr_len = lockArr1->LockArr_len +  lockArr2->LockArr_len;

    tmp->LockArr_val = (Lock *) malloc(tmp->LockArr_len * sizeof( Lock)); 

#ifdef PRINT

PrintInLogFile("Magic.hpf :%f %f \n", lockArr2->LockArr_val[0].MagicNum.hpf,
            lockArr1->LockArr_val[lockArr1->LockArr_len -1].MagicNum.hpf);

#endif

    if( lockArr2->LockArr_val[0].MagicNum.hpf <= lockArr1->LockArr_val[lockArr1->LockArr_len - 1].MagicNum.hpf) {

#ifdef PRINT
 
    PrintInLogFile( "going correctly %d \n", tmp->LockArr_len);

#endif

        for( i = 0; i < lockArr1->LockArr_len; i++) {
            CopyLock( &(tmp->LockArr_val[i]),
                    &(lockArr1->LockArr_val[i]));
        }

        for( i = 0; i < lockArr2->LockArr_len; i++) {
            CopyLock( &(tmp->LockArr_val[ i + lockArr1->LockArr_len]),
                    &(lockArr2->LockArr_val[i]));
        }
        PrintLockArr(tmp);
        return tmp;
    }

    else {
    PrintInLogFile( "going wrongly %d \n", tmp->LockArr_len);
        j = 0;
        i = 0;

        while( (i < lockArr1->LockArr_len) &&  
                    ( lockArr2->LockArr_val[0].MagicNum.hpf 
                            <= lockArr1->LockArr_val[i].MagicNum.hpf)) {
                CopyLock( &(tmp->LockArr_val[i]),
                    &(lockArr1->LockArr_val[i]));
                i++;
        }
             
        j = i;
        
        for( k = 0; k < lockArr2->LockArr_len; k++) {
                CopyLock( &(tmp->LockArr_val[i]),
                    &(lockArr2->LockArr_val[k]));
                i++;
        }

        if ( j < lockArr1->LockArr_len) {
                for( k = j; k < lockArr1->LockArr_len; k++) {
                    CopyLock(&(tmp->LockArr_val[i]),
                         &(lockArr1->LockArr_val[k]));
                    i++;
                }
        }
        return tmp;
    }
}

void PrintLockArr( LockArr* lockArr) {
    int i;

    if( lockArr == NULL) {
		PrintInLogFile("The lock array is empty AND its value is NULL \n");
	    return;
    }

    if( lockArr->LockArr_len == 0) {
		PrintInLogFile("The lock array is empty AND its size is zero\n");
	    return;
    }

#ifdef PRINT

    for( i =0; i < lockArr->LockArr_len; i++) {
        PrintInLogFile(" %d %d %f \t", (lockArr->LockArr_val[i]).LockId,
            (lockArr->LockArr_val[i]).NodeId, 
            (lockArr->LockArr_val[i]).MagicNum.hpf);
    }
	PrintInLogFile("\n");

#endif

}

void CopyLocalLock( LocalLock* lock1, LocalLock* lock2) {
    CopyLock( &(lock1->LockInf), &(lock2->LockInf));
    lock1->Status = lock2->Status;
    lock1->RibId    = lock2->RibId;
    lock1->SeqNum = lock2->SeqNum;
    PutInString( &(lock1->IPAddress), lock2->IPAddress.String_val);
}

LocalLockArr* appendLocalLockArr( LocalLockArr* lockList1, LocalLockArr* lockList2) {
    int     i;
    int     j;
    int     k;
    LocalLockArr* tmp;

    tmp = (LocalLockArr*) malloc (sizeof ( LocalLockArr));

    if (lockList1 == NULL)
    {
    if (lockList2 != NULL)
    {
        tmp->LocalLockArr_len = lockList2->LocalLockArr_len;
        tmp->LocalLockArr_val = (LocalLock *) 
                malloc(tmp->LocalLockArr_len * sizeof( LocalLock)); 
        for( i = 0; i < lockList2->LocalLockArr_len; i++)
        {
            CopyLocalLock( &(tmp->LocalLockArr_val[i]),
                    &(lockList2->LocalLockArr_val[i]));
        }
        return tmp;
    }
    return NULL; 
    }


    if (lockList2 == NULL)
    {
    if (lockList1 != NULL)
    {
        tmp->LocalLockArr_len = lockList1->LocalLockArr_len;
        tmp->LocalLockArr_val = (LocalLock *) 
                malloc(tmp->LocalLockArr_len * sizeof( LocalLock)); 
        for( i = 0; i < lockList1->LocalLockArr_len; i++)
        {
            CopyLocalLock( &(tmp->LocalLockArr_val[i]),
                    &(lockList1->LocalLockArr_val[i]));
        }
        return tmp;
    }
    return NULL;
    }

    tmp->LocalLockArr_len = lockList1->LocalLockArr_len +  
                            lockList2->LocalLockArr_len;

    tmp->LocalLockArr_val = (LocalLock *) 
            malloc(tmp->LocalLockArr_len * sizeof( LocalLock)); 

    for( i = 0; i < lockList1->LocalLockArr_len; i++)
    {
        CopyLocalLock( &(tmp->LocalLockArr_val[i]),
               &(lockList1->LocalLockArr_val[i]));
    }

    for( i = 0; i < lockList2->LocalLockArr_len; i++)
    {
         CopyLocalLock( &(tmp->LocalLockArr_val[ i + 
                                    lockList1->LocalLockArr_len]),
                    &(lockList2->LocalLockArr_val[i]));
    }

    return tmp;
}


void PrintLocalLockArr( LocalLockArr* lockArr)
{
    int i;

    if( lockArr == NULL) {
	return;
    }

#ifdef PRINT

    for( i =0; i < lockArr->LocalLockArr_len; i++) {
        PrintInLogFile(" %d %d %f %d %d %d \t", 
            (lockArr->LocalLockArr_val[i]).LockInf.LockId,
            (lockArr->LocalLockArr_val[i]).LockInf.NodeId, 
            (lockArr->LocalLockArr_val[i]).LockInf.MagicNum.hpf,
            (lockArr->LocalLockArr_val[i]).Status, 
            (lockArr->LocalLockArr_val[i]).RibId,
            (lockArr->LocalLockArr_val[i]).SeqNum);
        PrintInLogFile(" %s \t", (lockArr->LocalLockArr_val[i]).IPAddress.String_val);
    }
    PrintInLogFile("\n");

#endif

}

