#!/usr/bin/python
# -*- coding: utf-8 -*-


'''usage: pysed [-h] [-v] [-p] [-l] [-e] [-r] [-i]

Utility that parses and transforms text

optional arguments:
  -h, --help     : show this help message and exit
  -v, --version  : print version and exit
  -p, --print    : print text
		   e extract/, c chars/, s sum/
  -l, --lines	 : print lines
		   N,/, f first/, l last/, * all/
  -r, --replace  : replace text
		   m max(N)/, u upper/, l lower/ ['*']
  -i, --insert	 : insert text
                   m max(N)/

** N = Number, {Options}/'''



import re
import os
import sys
import platform


__prog__    = 'pysed'
__author__  = "dslackw"
__version__ = "0.1.3"
__license__ = "GNU General Public License v3 (GPLv3)"
__email__   = "d.zlatanidis@gmail.com"



if platform.system() == 'Linux':
	path = os.getcwd() + '/'

elif platform.system() == 'Windows':
	path = os.getcwd() + '\/'



def get_from_arg(arg):

	'''Get any string before char /'''

	result = []
	for char in arg:
        	result.append(char)
        	if char == '/':
                	break

	return ''.join(result).replace('/','')



def get_nums(text):

	'''Grep numbers from a string'''


	nums = '0123456789'

	result = []
	for t in text:
        	for n in nums:
                	if n == t:
                        	result.append(n)

	return ''.join(result)



def print_text(file, arg0, arg1, arg2, arg3):

	'''Print all results before 
        any changes save in a file'''

	result = []

	# get extra arguments
	options = get_from_arg(arg2)
	arg2 = arg2.replace(options + '/', '')

	# get numbers from extra arguments
	nums = get_nums(options)
	options = options.replace(nums, '')
	if nums == '':
		nums = 0
	
	try :
		file = open(path + file, 'r')
	       	read = file.read()
        	file.close()


		try:

		        find_text = re.findall(arg2, read)

			if find_text == []:
				sys.exit()

		except re.error:
			sys.exit()

		# print text
		if arg0 == '-p' or arg0 == '--print':

			options = get_from_arg(arg1)
			arg1 = arg1.replace(options + '/', '')

			try:
	                	find_text = re.findall(arg1, read)

        	        	if find_text == []:
                	        	sys.exit()

	                except re.error:
        	                sys.exit()

			if options == 's' or options == 'sum':

				words = read.split()
				chars = ''.join(words)
				for lines in range(len(read.splitlines())):
					pass
				print '%d lines' % (lines + 1)
				print '%d characters' % len(chars)
				print '%d words' % len(words)
				print '%d blanks' % (len(read) - len(chars))
				sys.exit()
			
			if options == 'c' or options == 'chars':
				
                                print 'find %d --> \'%s\'' % (len(find_text), arg1)
				sys.exit()

			if options == 'e' or options == 'extract':

		                print ' '.join(find_text)
				sys.exit()

			else:
		
				print read,
				sys.exit()
		
		# print lines
		elif arg0 == '-l' or arg0 == '--lines':
			options = get_from_arg(arg1)

			for line in read.splitlines():
			        result.append(line)

			if options == '*' or options == 'all':
				for num in result:
					print num
				sys.exit()

			elif options == 'f' or options == 'first':
				print result[0]
				sys.exit()

			elif options == 'l' or options == 'last':
				print result[len(result) -1] 
				sys.exit()

			else:

				try:
					line_nums = arg1.replace(',', '\n').split()
	
					for num in line_nums:
						if int(num) >= len(result):
							pass
						else:
							print result[int(num)]
					sys.exit()
				except ValueError:
					sys.exit()

		# print replace text
		elif arg0 == '-r' or arg0 == '--replace':

			result = read
			for text in set(find_text):
				if options == 'm' or options == 'max':
		               	        result = read.replace(text, arg3, int(nums))

				elif options == 'u' or options == 'upper':
					result = read.replace(text, arg3.upper())

				elif options == 'u*' or options == 'upper*':
					result = read.upper()

				elif options == 'l' or options == 'lower':
					result = read.replace(text, arg3.lower())			

				elif options == 'l*' or options == 'lower*':
					result = read.lower()

				else:
					result = result.replace(text, arg3)

		# print insert text
		elif arg0 == '-i' or arg0 == '--insert':

			result = read
			for text in set(find_text):
				if options == 'm' or options == 'max':
		               	        result = read.replace(text, text + arg3, int(nums))
				
				else:
					result = result.replace(text, text + arg3)
		else:

			arguments_error(arg0, '')			

	        if result != []:
        	        print result,	

	except IOError:
                print ("%s: can't read %s: No such file or directory" % (__prog__, file))




def replace_text(file, arg1, arg2):

	'''Replace the text data and save changes to the file'''

	result = []

	# get extra arguments
	options = get_from_arg(arg1)
        arg1 = arg1.replace(options + '/', '')

	# get numbers from extra arguments
        nums = get_nums(options)
        options = options.replace(nums, '')
        if nums == '':
                nums = 0

	try:

	        file =  open(path + file, 'r+')
		read = file.read()
	
		try:

			find_text = re.findall(arg1, read)

			if find_text == []:
                                sys.exit()

		except re.error:
			sys.exit()

		# replace text
		result = read
                for text in set(find_text):
	                if options == 'm' or options == 'max':
		                result = read.replace(text, arg2, int(nums))

                	elif options == 'u' or options == 'upper':
        	        	result = read.replace(text, arg2.upper())

	                elif options == 'u*' or options == 'upper*':
		                result = read.upper()

                	elif options == 'l' or options == 'lower':
                        	result = read.replace(text, arg2.lower())

	                elif options == 'l*' or options == 'lower*':
        	                result = read.lower()

                	else:
                        	result = result.replace(text, arg2)
		
		# write changes to file
	        if result != []:
			file.seek(0)
			file.truncate()
			file.write(result)

		file.close()

	except IOError:
		print ("%s: can't read %s: No such file or directory" % (__prog__, file))



def append_text(file, arg1, arg2):

	'''Insert text to a file'''

	result = []

	# get extra arguments
	options = get_from_arg(arg1)
        arg1 = arg1.replace(options + '/', '')

	# get numbers from extra arguments
        nums = get_nums(options)
        options = options.replace(nums, '')

        if nums == '':
                nums = 0

	try:

		file = open(path + file, 'r+')
        	read = file.read()
	
		try:

		        find_text = re.findall(arg1, read)

			if find_text == []:
                                sys.exit()

		except re.error:
        	        sys.exit()
	
		# append text
		result = read
		for text in set(find_text):
			if options == 'm' or options == 'max':
				result = read.replace(text, text + arg2, int(nums))

                	else:
   				result = result.replace(text, text + arg2)


		# write changes to file
	        if result != []:
			file.seek(0)
			file.truncate()
	                file.write(result)

	        file.close()

	except IOError:
		print ("%s: can't read %s: No such file or directory" % (__prog__, file))



def version():

	'''Print version, license and email'''

	print ('version :'),  __version__	
	print ('License :'),  __license__
	print ('Email   :'),  __email__



def arguments_view():

	'''Print arguments options'''

	print ('usage: pysed [-h] [-v] [-p] [-l] [-e] [-r] [-i]\n')
        print ('Utility that parses and transforms text\n')
        print ('optional arguments:')
        print ('  -h, --help     : show this help message and exit')
        print ('  -v, --version  : print version and exit')
        print ('  -p, --print    : print text')
	print ('		   e extract/, c chars/, s sum/')
	print ('  -l, --lines	 : print lines')
	print ('		   N,/, f first/, l last/, * all/')
        print ('  -r, --replace  : replace text')
	print ('		   m max(N)/, u upper/, l lower/ [\'*\']')
        print ('  -i, --insert	 : insert text')
	print ('                   m max(N)/\n')
	print ('** N = Number, {Options}/')


def arguments_error(arg0, argx):

	'''Print errors arguments'''

	print ('usage: %s [-h] [-v] [-p] [-l] [-r] [-i]\n' % __prog__)

	if arg0 == '':
		print ('%s: error: argument: expected one argument' % __prog__)


	elif arg0 in ['-p', '--print',
		      '-l', '--lines',
		      '-r', '--replace',
		      '-i', '--insert']:
		print ('%s: argument %s: expected at least one argument' % (__prog__, arg0))

	else:
		print ('%s: error: unrecognized arguments: %s %s' % (__prog__, arg0, ' '.join(argx)))



def main():

	arg = sys.argv
	arg.pop(0)
	

	if len(arg) == 2:
		file = arg[1]

        elif len(arg) == 3:
                file = arg[2]

	elif len(arg) == 4:
		file = arg[3]

	elif len(arg) == 5:
		file = arg[4]


	if len(arg) == 0:
		arguments_error('', '')

	elif len(arg) == 1 and arg[0] == '-h' or len(arg) == 1 and arg[0] == '--help':
		arguments_view()

	elif len(arg) == 1 and arg[0] == '-v' or len(arg) == 1 and arg[0] == '--version':
		version()

	elif len(arg) == 2 and arg[0] == '-p' or len(arg) == 2 and arg[0] == '--print':
		print_text(file, arg[0], '', '', '')

	elif len(arg) == 3 and arg[0] == '-p' or len(arg) == 3 and arg[0] == '--print':
		print_text(file, arg[0], arg[1], '', '')
		
	elif len(arg) == 5 and arg[1] == '-p' or len(arg) == 5 and arg[1] == '--print':
		print_text(file, arg[0], arg[1], arg[2], arg[3])

	elif len(arg) == 3 and arg[0] == '-l' or len(arg) == 3 and arg[0] == '--lines':
                print_text(file, arg[0], arg[1], '', '')

	elif len(arg) == 4 and arg[0] == '-r' or len(arg) == 4 and arg[0] == '--replace':
		replace_text(file, arg[1], arg[2])

	elif len(arg) == 4 and arg[0] == '-i' or len(arg) == 4 and arg[0] == '--insert':
		append_text(file, arg[1], arg[2])

	elif not any([
		len(arg) == 1 and arg[0] == '-p', len(arg) == 1 and arg[0] == '--print',
		len(arg) == 1 and arg[0] == '-l', len(arg) == 1 and arg[0] == '--lines',
		len(arg) == 1 and arg[0] == '-r', len(arg) == 1 and arg[0] == '--replace',
		len(arg) == 1 and arg[0] == '-i', len(arg) == 1 and arg[0] == '--insert',
		]):
		arguments_error(arg[0], arg[1:])

	elif arg[0] in ['-p', '--print',
			'-l', '--lines',
			'-r', '--replace',
		        '-i', '--insert']:
		arguments_error(arg[0], arg[1:])



if __name__ == "__main__":
    main()
