/*!
 **  bauer-zip -- Zip and unzip files and folders.
 **  Copyright (c) 2014 Yuri Neves Silveira <http://yneves.com>
 **  Licensed under The MIT License <http://opensource.org/licenses/MIT>
 **  Distributed on <http://github.com/yneves/node-bauer-zip>
 */
// - -------------------------------------------------------------------- - //
// - libs

var lib = {
	fs : require("fs"),
	path : require("path"),
	jszip : require("jszip"),
	decompress : require("decompress-zip"),
	factory : require("bauer-factory"),
};

// - -------------------------------------------------------------------- - //

var z = lib.factory.object({
	
		multizip : {
			asf: function(rootDirs, saveTo, done){
				//console.log('multizipping');
				var maincount = rootDirs.length;
				var includes = []; for (var i=0; i<maincount; i++) includes.push(true);
				
				var zip = new lib.jszip();

				for (var i=0; i<rootDirs.length; i++){
					if (rootDirs[i].substring(rootDirs[i].length-1) == '/') includes[i] = false;
					rootDirs[i] = lib.path.resolve(rootDirs[i]);
				}

				function recurse(fullPath, parentZip, callback, index){

					lib.fs.stat(fullPath, function(err, stat){

						if (err) return callback(err);
						
						var file = lib.path.basename(fullPath);	
						if (stat.isDirectory()){
							//console.log('dir', fullPath);
							if (fullPath != rootDirs[index]) parentZip = parentZip.folder(file);
							else if (includes[index]) parentZip = parentZip.folder(file);
				
							lib.fs.readdir(fullPath, function(err, files){
								
								if (err) return callback(err);
								
								if (!files.length) return callback();
								var count = files.length;
								
								files.forEach(function(file){
									
									var filePath = lib.path.resolve(fullPath, file);
									
									recurse(filePath, parentZip, function(err){
										if (!--count) callback(err);
									}, index);
									
								});
								
							});
						} 
						else {
							//console.log('file', fullPath);
							lib.fs.readFile(fullPath, function(err, data){
								parentZip.file(file, data);
								callback(err);
							});
						}
					});
					
				}
				
				var maincounter = 0;
				//console.log('maincount', maincount);
				for (var i=0; i<maincount; i++){
					//console.log('recurse', i);
					recurse(rootDirs[i], zip, function(error){
						//console.log('maincounter', ++maincounter);
						++maincounter;
						if (maincounter == maincount){
							if (error) done(error);
							else {
								var buffer = zip.generate({
									compression : "DEFLATE",
									type : "nodebuffer",
								});
								lib.fs.writeFile(saveTo, buffer, {encoding : "binary"}, function(error){
									done(error);
								});
							}
						}
					}, i);
				}
				
				return z;
			}
		},
		zip : {

			ss : function(rootDir, saveTo){
				var zip = new lib.jszip();
				rootDir = lib.path.resolve(rootDir);
				function recurse(fullPath, parentZip){
					//console.log('recurse', fullPath);
					var stat = lib.fs.statSync(fullPath);
					var file = lib.path.basename(fullPath);
					if (stat.isDirectory()){
						
						var folderZip = parentZip.folder(file);
						var files = lib.fs.readdirSync(fullPath);
						var count = files.length;
						files.forEach(function(file){
							var filePath = lib.path.resolve(fullPath, file);
							recurse(filePath, folderZip);
						});
					} else {
						var data = lib.fs.readFileSync(fullPath);
						parentZip.file(file, data);
					}
				}
				recurse(rootDir, zip);
				var buffer = zip.generate({
						compression : "DEFLATE",
						type : "nodebuffer",
					});
				lib.fs.writeFileSync(saveTo, buffer, {
					encoding : "binary"
				});
				return z;
			},

			// .zip(source,target,callback)
			ssf : function(rootDir, saveTo, done){
				
				var zip = new lib.jszip();
				var include = true;

				if (rootDir.substring(rootDir.length-1) == '/') include = false;
				rootDir = lib.path.resolve(rootDir);

				function recurse(fullPath, parentZip, callback){

					lib.fs.stat(fullPath, function(err, stat){

						if (err) return callback(err);
						var file = lib.path.basename(fullPath);
					
						
						if (stat.isDirectory()){
							
							if (fullPath != rootDir) parentZip = parentZip.folder(file);
							else if (include) parentZip = parentZip.folder(file);
				
							lib.fs.readdir(fullPath, function(err, files){
								
								if (err) return callback(err);
								if (!files.length) return callback();
								var count = files.length;
								
								files.forEach(function(file){
									
									var filePath = lib.path.resolve(fullPath, file);
									
									recurse(filePath, parentZip, function(err){
										if (!--count) callback(err);
									});
									
								});
								
							});
						} 
						else {
							lib.fs.readFile(fullPath, function(err, data){
								parentZip.file(file, data);
								callback(err);
							});
						}
					});
					
				}
				
				recurse(rootDir, zip, function(error){
					if (error) done(error);
					else {
						var buffer = zip.generate({
							compression : "DEFLATE",
							type : "nodebuffer",
						});
						lib.fs.writeFile(saveTo, buffer, {encoding : "binary"}, function(error){
							done(error);
						});
					}
				});
				
				return z;
			}

		},

		unzip : {

			// .unzip(source,target,callback)
			ssf : function(zipPath, directoryPath, done){
				var name = lib.path.basename(zipPath);
				var unzipper = new lib.decompress(zipPath);
				unzipper.on("error", function(error){
					done(error);
				});
				unzipper.on("extract", function(){
					done();
				});
				unzipper.extract({
					path : directoryPath,
				});
				return z;
			},

		},

	});

// - -------------------------------------------------------------------- - //

module.exports = z;

// - -------------------------------------------------------------------- - //
