#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h>
#include <errno.h>

#include <time.h>

void *sumaVector1(void* arg){
    int * vector=(int*)arg;
    long*suma=(long*)malloc(sizeof(long));
    *suma=0;

    for (int j; j<5;j++){
        *suma=*suma+vector[j];
    }

    printf("    |HEBRA HIJA| : Suma=%ld\n", *suma);
    pthread_exit((void*) suma);
}

void *sumaVector2(void* arg){
    int *vector=(int*)arg;
    long *suma=(long*)malloc(sizeof(long));
    *suma=0;

    for (int j; j<2;j++){
        *suma=*suma+vector[j];
    }

    printf("    |HEBRA HIJA| : Suma=%ld\n", *suma);
    pthread_exit((void*) suma);
}

int main(int argc, char** argv){
	if (argc < 2) {
        fprintf(stderr, "Faltan argumentos...\n");
        exit(EXIT_FAILURE);
    }

    int vect[10];
    int error, valor_join; 
    long num_threads=atol(argv[1]);
	long valor=0;
    long *ret;

    srand(time(NULL));
    for (int i=0; i<10;i++){
        vect[i]=rand()%(9)+1; 
    }

    if (num_threads==2){
        printf("|HEBRA PADRE| : OPCION DE 2 HEBRAS ELEGIDA...\n");
        pthread_t threads[num_threads];
        int aux=0;
        int vaux1[5], vaux2[5];

        for (int j=0; j<5;j++){
            vaux1[j]=vect[j];
            vaux2[j]=vect[9-j];
            printf("%d\n", vaux1[j]);
            printf("%d\n", vaux2[j]);
        }

        for(int t=0;t<num_threads-1;t++) 
	    {
		
		    printf("|HEBRA PADRE| : Creando hebra %d...\n", t);
            if(t=0){
		        error = pthread_create(&threads[t], NULL, (void *) sumaVector1, (void *) vaux1);
            }else{
                error = pthread_create(&threads[t], NULL, (void *) sumaVector1, (void *) vaux2);
            }

       	    if (error) 
		    {
		        perror("Error joining thread\n");
                printf("errno value= %d\n", errno); 
                exit(EXIT_FAILURE);
		    }
	    }

        for(int i=0;i<num_threads;i++) 
	    {
	       valor_join = pthread_join(threads[i], (void**)&ret);

	       if(valor_join!=0)
	       {
	         perror("Fallo en pthread_join()...\n");		
	         exit(EXIT_FAILURE);
	       }

           valor+=*ret;
	    }
        printf("|HEBRA PADRE| : Suma total=%ld...\n", valor);

    } else if(num_threads==5){
        pthread_t threads[num_threads];
        int aux=0;
        int vaux[2];

        printf("|HEBRA PADRE| : OPCION DE 5 HEBRAS ELEGIDA...\n");
        for(int t=0;t<num_threads-1;t++) 
	    {
		    for (int i=0; i<2;i++){
                vaux[i]=vect[aux];
                aux++;
            }

		    printf("|HEBRA PADRE| : Creando hebra %d...\n", t);
            error = pthread_create(&threads[t], NULL, (void *) sumaVector2, (void *) vaux);
       	    if (error) 
		    {
		        perror("Error create thread\n");
                printf("errno value= %d\n", errno); 
                exit(EXIT_FAILURE);
		    }
	    }

        for(int i=0;i<num_threads;i++) 
	    {
	       valor_join = pthread_join(threads[i], (void**)&ret);

	       if(valor_join!=0)
	       {
	            perror("Fallo en pthread_join()...\n");		
	            exit(EXIT_FAILURE);
	       }

           valor+=*ret;
	    }
        printf("|HEBRA PADRE| : Suma total=%ld...\n", valor);
    }else{
        printf("Numero de hebras incorrecto, solo 2 o 5. Num elegido: %ld \n", num_threads);
    }

}