/***************************************************************************
 *   Copyright (C) 2005 by Jared Bruni                                     *
 *   jared@lostsidedead.com                                                           *
 *                                                                         *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <string>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using std::endl;


inline void errormsg(const char *str) {
	perror(str);
}

inline int read_all(int sock) {
	int rt_val = 0;
	static char buffer[1024];
	while((rt_val = read(sock,buffer,1024)) != -1 && rt_val != 0) {
		std::cout << buffer;
		memset(buffer,0,sizeof(buffer));
		
	}
	std::cout << "\nfinished downloading file.\n";
}



int download_and_build(char *ip, char *directory) {
	int sock, new_socket, port;
	struct sockaddr_in cli;
	sock = socket(AF_INET,SOCK_STREAM,0);
	
	if(sock < 0) {
		errormsg("Error creating socket!.");
		return -1;
	}
	
	bzero((char*)&cli, sizeof(cli));
	cli.sin_family = AF_INET;
	cli.sin_port = htons(1024);
	cli.sin_addr.s_addr = inet_addr(ip);
	bool connected = false;
	if(connect(sock,(struct sockaddr*)&cli, sizeof(cli)) < 0) {
		errormsg("Error connecting..");
		close(sock);
		return 0;	
	}
	else connected = true;
	
	std::string the_directory = std::string("./") + directory + "/";
	static char data[256];
	memset(data,0,sizeof(data));
	static int rt_val = 0;
	rt_val = read(sock, data, 255);
	if(rt_val < 0) {
		errormsg("Error on read!.\n");
		close(sock);
		return 0;
	}
	else {
		std::string src = data;
		if(src.find("lsdmake") != -1) {
		std::cout << src << "\n";
		memset(data,0,sizeof(data));
		sprintf(data,"get %s", directory);
		rt_val = write(sock, data, strlen(data));
		if(rt_val < 0) {
		  errormsg(" Error couldnt write to socket.. ");
	 	 close(sock);
		  return 0;	
		}
	     	   while(connected == true) {
		   memset(data,0, sizeof(data));
		   rt_val = read(sock, data, sizeof(data));
		   data[rt_val] = 0;
		   if(rt_val < 0) {
		   	errormsg("Error on read.");
			close(sock);
			return 0;
		   }
		   else {
			std::string cmd = std::string("mkdir -p ") + the_directory;
			system(cmd.c_str());
		    	std::string file_name = data;
			size_t name = file_name.find(":");
			size_t t = file_name.find("term...");
			if(t != -1) {
				std::cout << "Closing connection..\n";
				break;
			}
			if(name != -1) {
				std::string fname = the_directory + file_name.substr(file_name.find(':')+1, file_name.length());
				std::fstream file;
				unsigned long total_bytes = 0, bytes_read = 0;
				total_bytes = atol(file_name.substr(0,file_name.find(':')).c_str());
				std::cout << "creating file... " << fname << " " << total_bytes << " bytes.." << "\n";
				file.open(fname.c_str(),std::ios::binary | std::ios::out);
				while(true) {
					char data[256];
					bzero((char*)data,sizeof(data));
					rt_val = read(sock,data,sizeof(data));
					data[rt_val] = 0;
					bytes_read += rt_val;
					if(bytes_read >= total_bytes) { 
					        if(rt_val > total_bytes) 
						file.write((char*)data,total_bytes);
						else {
							file.write((char*)data, total_bytes%rt_val );
						}
						file.close();
						std::cout << "Read : " << bytes_read << " Closing file\n";
					 	break;
					}
					else {
						std::cout << "Read: " << bytes_read << "/" << total_bytes << "\n";
						file.write((char*)data,sizeof(data));
					}
				}
			}
		}
	} 
} 

		std::cout << "Bulding sources..\n";
		std::string cmd = "make -C" + the_directory;
		std::cout << the_directory << endl;
		system(cmd.c_str());
}
	
	return 0;
}

int main(int argc, char *argv[])
{

	if(argc == 3) {
	download_and_build(argv[1],argv[2]);
	} else {
		std::cout << "Error invalid arguments specified.\n";
	}

 	 return 0;
}
