#!/usr/bin/env python
# @Author: @amarlearning
# @Date:   2017-01-15
# @Email:  amar.om1994@gmail.com  
# MIT License. You can find a copy of the License
# @http://amarlearning.mit-license.org

import os, re
import sys, string
import json
import urllib2
from clint.textui import colored, puts

class GithubSectory():
	""" docstring for GithubSectory : Python script to download Github Project Subdirectory! """
	

	def __init__(self):
		self.arg = sys.argv
		self.link = ""
		self.ghapi = "https://api.github.com/repos/"
		self.gh = "https://github.com/"

	def clear(self):

		"""for removing the clutter from the screen when necessary"""
		
		os.system('cls' if os.name == 'nt' else 'clear')


	def getSysArguments(self):

		""" Lets see what kind of input user has given to us """
	
		try:
			self.link = sys.argv[1]
		except Exception as e:
			puts(colored.red("Error : Not argument. Truncating process!"))
			sys.exit(0)
		
		if not re.search(r'github.com', self.link):	
			
			puts(colored.magenta("[ Validating Input Parameters ]"))
			
			for index, arg in enumerate(self.arg):
				if arg == "-r":
					self.repo = self.arg[index+1]
				if arg == "-d":
					self.dir = self.arg[index+1]
				if arg == "-b":
					self.branch = self.arg[index+1]

			try:
				self.link = self.ghapi + sys.argv[1]
			except Exception as e:
				puts(colored.red("Error : User/Organisation not mentioned. Truncating process!"))
				sys.exit(0)

			try:
				self.link = self.link + "/" + self.repo
			except Exception as e:
				puts(colored.red("Error : Repository not mentioned. Truncating process!"))
				sys.exit(0)

			try:
				self.link = self.link + "/contents/" + self.dir
				try:
					self.link = self.link + "?ref=" + self.branch
					self.downloadMe(self.link)
				except AttributeError:
					self.downloadMe(self.link)
			except AttributeError:
				self.link = self.gh + sys.argv[1] + "/" + self.repo + ".git"
				self.downloadMe(self.link)
		
		else:
			puts(colored.magenta("[ Validating Input URL ]"))
			if len(self.link.split("/")) < 7:
				puts(colored.green("Normal Link, use git commands to clone repository!"))
			else:
				self.link = self.link.replace(self.gh, self.ghapi)
				self.link = self.link.replace('tree', 'contents')
				self.linkList = self.link.split("/")
				self.repo = self.dir = self.linkList[8]
				self.link = self.link.replace(self.linkList[7]+"/", '')
				self.link = self.link + "/?ref=" + self.linkList[7]
				self.downloadMe(self.link)


	def downloadMe(self, parameter):

		""" Method to download file, link is passed via parameter """

		puts(colored.yellow("[ Getting folder content ]"))
		self.downloadLink = parameter
		try:
			self.parsed = json.loads(urllib2.urlopen(self.downloadLink).read())
		except urllib2.HTTPError as err:
			if err.code == 404:
				puts(colored.red("[ Invalid URL! Maybe private repo ]"))
				sys.exit(0)
			else:
				raise
				sys.exit(0)

		if not os.path.exists(self.dir):
			os.makedirs(self.dir)
		self.tempPath = os.path.join(os.getcwd(), self.dir)
		puts(colored.green("[ Downloading all required files ]"))
		self.workingRecursively(self.tempPath, self.parsed)
		puts(colored.green("[ Finished ]"))


	def workingRecursively(self, filepath, filedata):
		
		""" Get the List of all filenames and link of required subdirectory """

		for file in filedata:
			if file['type'] == "file":
				fileCreate = open(os.path.join(filepath, file['name']),'a+')
				fileCreate.write(urllib2.urlopen(file['download_url']).read())
				fileCreate.close()
			else:
				changedPath = os.path.join(filepath, file['name'])
				if not os.path.exists(changedPath):
					os.makedirs(changedPath)
				newFileData = json.loads(urllib2.urlopen(file['url']).read())
				self.workingRecursively(changedPath, newFileData)


if __name__ == '__main__':
	GithubSectory().getSysArguments()
