var json2csv = require('json2csv');
var _ = require('base-utils')._;

// Copied from Quora;
exports.CSVtoArray = function(text) {
     var re_valid =  /^\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*(?:,\s*(?:'[^'\\]*(?:\\[\S\s][^'\\]*)*'|"[^"\\]*(?:\\[\S\s][^"\\]*)*"|[^,'"\s\\]*(?:\s+[^,'"\s\\]+)*)\s*)*$/;
     var re_value =  /(?!\s*$)\s*(?:'([^'\\]*(?:\\[\S\s][^'\\]*)*)'|"([^"\\]*(?:\\[\S\s][^"\\]*)*)"|([^,'"\s\\]*(?:\s+[^,'"\s\\]+)*))\s*(?:,|$)/g;
    if (!re_valid.test(text)) return null;
    var a = [];                    
    text.replace(re_value,
        function(m0, m1, m2, m3) {
            if      (m1 !== undefined) a.push(m1.replace(/\\'/g, "'"));
            else if (m2 !== undefined) a.push(m2.replace(/\\"/g, '"'));
            else if (m3 !== undefined) a.push(m3);
            return ''; 
        });
    if (/,\s*$/.test(text)) {
		a.push('');
	}
    return a;
};

exports.tsv2json = function(rows) {
	var fields = rows[0].split('\t');

	return _.map( rows.slice(1), function(row) {
		return _.reduce(fields, function(result, field, offset) {
			result[_.trim(field || '').replace(/\"/g, '')] = _.isString(this[offset]) && this[offset].replace(/\"/g, '');
			return result;
		}, {}, row.split('\t'));
	} );	
};

exports.csv2json = function(rows) {
	var fields;
	
	if (rows[0].split('\t').length > 1) {
		return exports.tsv2json( rows );
	}
	
	fields = exports.CSVtoArray( rows[0] );
	return _.map(rows.slice(1), function(row) {
		return _.reduce(fields, function(result, field, offset) {
			result[_.trim(field)] = this[offset];
			return result;
		}, {}, exports.CSVtoArray( row.replace(/\'/g, '') ));
	});
};

exports.convert2targetSchema = function(targetSchema, json) {
	json = _.isArray( json ) ? json : [ json ];	
	
	// filter empty objects
	json = _.filter(json, function(row) { return _.keys(row).length; });
	return _.map(json, function(row) {
		return _.reduce(targetSchema, function(result, val, key) {
			result[key] = this[val[key]] || this[key] ||  '';
			if (!result[key] && val.hasOwnProperty('default')) result[key] = val.default; 
			if (_.isFunction(val.transform)) {
				result[key] = val.transform.call(row, result[key] );
			}
			return result;
		}, {}, row);
	});
};

exports.json2xml = function(obj) {
	var job2xml = function(job) {
		return _.buildHTML('job', _.map(obj.fields, function(field) {
			return job[field] && _.buildHTML(field, job[field]) || '';
		}).join('') );
	}
	
	return _.buildHTML('jobs', _.map(obj.data, job2xml).join('') );	

};

exports.json2csv = json2csv;

/* Object form:
var obj = {
	"somekey": {type: "string", required: true, default: "somevalue", somekey: "sourcekey"}
}
*/
exports.getRequired = function(schemaObj) {
	return _.reduce(schemaObj, function(res, val, key) {
		if (val.required) {
			res.push( key );
		}
		return res;
	}, []);
};



