/*  This file is part of lsnet. 
    Copyright (C) 2009-2010  Sterling Pickens
    Lsnet is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Lsnet is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with lsnet.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "netinfo.h"

struct net_data net;

void Net_ten_min(){
	FILE* fp;
	struct tm *local;
	time_t t;
	local = localtime(&t);
	unsigned int count_minutes = 0;
	unsigned int count_entries = 0;
	const unsigned int str_size = ( strlen(asctime(local)) + ceil(log( pow(2, sizeof(double)*8) )*4) + 4 + 1) + 1;   
	char *ten_str; //(date + 4 spaces + 4 doubles + newline)*10 + null
	char *tmp_str;
	tmp_str = (char *)malloc( str_size - strlen(asctime(local)) - 1 );
	ten_str = (char *)malloc(10*str_size);

	while (1 == 1){
		memset ((void*) ten_str, '\0', 10*str_size);
		for(count_minutes = 0; count_minutes < 10; count_minutes++){
			Net_one_min();
			t = time(NULL);
			local = localtime(&t);
			strcat(ten_str, (const char *)asctime(local));
			ten_str[strlen(ten_str)-1]='\0'; //newline gone
			for(count_entries = 0; count_entries < 4; count_entries++){		
				if(sprintf( tmp_str, " %lf", net.min_one[count_entries]) < 1){
					//FAIL
					printf("Error: sprintf has failed!\n");
					exit(1);
				}
				strcat(ten_str, (const char *)tmp_str);
			}
			strcat(ten_str, "\n");
		}
		if( fp = fopen(global_strs.net_log, "a") ){
			fprintf(fp, "%s", ten_str );
		}
		fclose( fp );
	}
}

void Net_one_min(){
	unsigned int count_poll    = 0;
	unsigned int count_entries = 0;
	double walltime            = 0;

	walltime = 0;
	for(count_entries=0; count_entries<4; count_entries++){
		net.min_one[count_entries] = 0;
	}
	for(count_poll=0; count_poll<net.polls; count_poll++){
		walltime += Get_netinfo();
		for(count_entries=0; count_entries<4; count_entries++){
			//sum of results
			net.min_one[count_entries] += net.poll_one[0][count_entries];
		}
	}
	for(count_entries=0; count_entries<4; count_entries++){
		// KiB/s
		net.min_one[count_entries] /= walltime;
	}
}

double Get_netinfo() 
{
        FILE* fp;

        struct timeval starttime,endtime;

	double netin;
        unsigned int count = 0;
	unsigned int count2;
	//  eth0:3100353807 12255870    0    0    0     0          0         0 1925386292 5100360    0    0    0     0       0          0
	// 7 leading chars + (13)big enough for 9.99 petabytes + 9 spaces(stopping at 5100360) + newline + null 
	//can be improved later
	const unsigned int buf_size = 7 + 13*10 + 9 + 1 + 1;  
        char buf[buf_size];
        char temp[3];           
        char bufstr[sizeof(temp)*14];

        if( ( fp = fopen( "/proc/net/dev", "r" ) ) == NULL ) {
                fprintf( stderr, "Error opening /proc/net/dev\n" );
                exit( 1 );
        }
        gettimeofday(&starttime, NULL);
        while( fgets(buf, sizeof(buf), fp) != NULL)
        {

		//eth0:1973355872 44136361    0    0    0     0          0         0 1177611554 19597524    0    0    0     0       0          0
		count = 0;
		if (buf[count] == ' '){
			while(buf[count] == ' ') {
				count++;
			}
		}
		if (buf[count] == 'e'){
			count++;
                	if (buf[count] == 't'){
				count++;
                        	if (buf[count] == 'h'){
					count++;
                                	if (buf[count] == '0'){ 
						count++;
                                        	if (buf[count] == ':')
                                                {
								
								count2 = count + 1;
								while(buf[count2] == ' ') {
									count2++;
								}
								temp[0]=buf[count2];
								temp[1]=0;
								strcpy(bufstr, temp);
								for( (count2 = count2 + 1); (count2 <= strlen(buf) && buf[count2] != ' '); count2++){
									temp[0]=buf[count2];
									temp[1]=0;
									strcat(bufstr,temp);									

								}
								net.poll_one[0][0] = atof(bufstr);
								memset ((void*) bufstr, '\0', sizeof (bufstr));
                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
								for( (count2 = count2); (count2 <= strlen(buf) && buf[count2] != ' '); count2++){
									temp[0]=buf[count2];
									temp[1]=0;
									strcat(bufstr,temp);
								}
								net.poll_one[0][1] =  atof(bufstr);
								memset ((void*) bufstr, '\0', sizeof (bufstr));

								//6 series of numbers/spaces
                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
									//1
								while((buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7' 
								||buf[count2] == '8' || buf[count2] == '9') && (buf[count2] != ' ')) {
									count2++;								
								}
                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
									//2
                                                                while((buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9') && (buf[count2] != ' ')) {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
									//printf("STEP3\n");
                                                                while((buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9') && (buf[count2] != ' ')) {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
									//printf("STEP4\n");
                                                                while((buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9') && (buf[count2] != ' ')) {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
                                                                while((buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9') && (buf[count2] != ' ')) {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }

                                                                while((buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9') && (buf[count2] != ' ')) {
                                                                        count2++;
                                                                }
                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
								///end of spaces/numbers

                                                                for( (count2 = count2); (count2 <= strlen(buf) && buf[count2] != ' '); count2++){
                                                                        temp[0]=buf[count2];
                                                                        temp[1]=0;
                                                                        strcat(bufstr,temp);
                                                                }
								net.poll_one[0][2] =  atof(bufstr);
                                                                memset ((void*) bufstr, '\0', sizeof (bufstr));

                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }

                                                                for( (count2 = count2); (count2 <= strlen(buf) && buf[count2] != ' '); count2++){
                                                                        temp[0]=buf[count2];
                                                                        temp[1]=0;
                                                                        strcat(bufstr,temp);
                                                                }
								net.poll_one[0][3] =  atof(bufstr);
                                                                memset ((void*) bufstr, '\0', sizeof (bufstr));

                                                }
                                        }
                                }
                        }
                }

	}
	fclose( fp );
	
	sleep(net.frequency);

        if( ( fp = fopen( "/proc/net/dev", "r" ) ) == NULL ) {
                fprintf( stderr, "Error opening /proc/net/dev\n" );
                exit( 1 );
        }
        gettimeofday(&endtime, NULL);
        while( fgets(buf, sizeof(buf), fp) != NULL)
        {
                count = 0;
                if (buf[count] == ' '){                         
                        while(buf[count] == ' ') {
                                count++;
                        }
                }
                        
                if (buf[count] == 'e'){
			count++;
                        if (buf[count] == 't'){
				count++;
                                if (buf[count] == 'h'){
					count++;
                                        if (buf[count] == '0'){ 
						count++;
                                                if (buf[count] == ':')
                                                {
                                                                count2 = count + 1;
                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
                                                                temp[0]=buf[count2];
                                                                temp[1]=0;
                                                                strcpy(bufstr, temp);
                                                                for( (count2 = count2 + 1); (count2 <= strlen(buf) && buf[count2] != ' '); count2++){
                                                                        temp[0]=buf[count2];
                                                                        temp[1]=0;
                                                                        strcat(bufstr,temp);
                         
                                                                }
								net.poll_one[1][0] =  atof(bufstr);
                                                                memset ((void*) bufstr, '\0', sizeof (bufstr));

                                                                while(buf[count2] == ' ') {
                                                                        count2++; 
                                                                }
                                                                for( (count2 = count2); (count2 <= strlen(buf) && buf[count2] != ' '); count2++){
                                                                        temp[0]=buf[count2];
                                                                        temp[1]=0;
                                                                        strcat(bufstr,temp);
                                                                }
                                                                net.poll_one[1][1] =  atof(bufstr);
                                                                memset ((void*) bufstr, '\0', sizeof (bufstr));

                                                                //6 series of numbers/spaces
                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
                                                                while(buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9' && buf[count2] != ' ') {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9' && buf[count2] != ' ') {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
                                                                while(buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9' && buf[count2] != ' ') {
                                                                        count2++;
                                                                }
                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9' && buf[count2] != ' ') {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9' && buf[count2] != ' ') {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }

                                                                while(buf[count2] == '0' || buf[count2] == '1' || buf[count2] == '2' || buf[count2] == '3' || buf[count2] == '4' ||buf[count2] == '5' || buf[count2] == '6' || buf[count2] == '7'
                                                                ||buf[count2] == '8' || buf[count2] == '9' && buf[count2] != ' ') {
                                                                        count2++;
                                                                }
                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
                                                                ///end of spaces/numbers

                                                                for( (count2 = count2); (count2 <= strlen(buf) && buf[count2] != ' '); count2++){
                                                                        temp[0]=buf[count2];
                                                                        temp[1]=0;
                                                                        strcat(bufstr,temp);
                                                                }
                                                                net.poll_one[1][2] =  atof(bufstr);
                                                                memset ((void*) bufstr, '\0', sizeof (bufstr));

                                                                while(buf[count2] == ' ') {
                                                                        count2++;
                                                                }
                                                                for( (count2 = count2); (count2 <= strlen(buf) && buf[count2] != ' '); count2++){
                                                                        temp[0]=buf[count2];
                                                                        temp[1]=0;
                                                                        strcat(bufstr,temp);
                                                                }
                                                                net.poll_one[1][3] =  atof(bufstr);
                                                                memset ((void*) bufstr, '\0', sizeof (bufstr));
                                                }
                                        }
                                }
                        }
                }                                                               
        }
        fclose( fp );

	//set totals
	net.poll_one[0][0] = (net.poll_one[1][0] - net.poll_one[0][0]) / 1024;
        net.poll_one[0][1] = net.poll_one[1][1] - net.poll_one[0][1];
        net.poll_one[0][2] = (net.poll_one[1][2] - net.poll_one[0][2]) / 1024;
        net.poll_one[0][3] = net.poll_one[1][3] - net.poll_one[0][3];


        return ((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
}

