# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt

#!/usr/bin/env python
from __future__ import unicode_literals
import os, sys
import argparse
import subprocess

is_redhat = is_debian = None
root_password = None

requirements = [
	"chardet", 
	"cssmin", 
	"dropbox", 
	"google-api-python-client", 
	"gunicorn", 
	"httplib2", 
	"jinja2", 
	"markdown2", 
	"markupsafe", 
	"mysql-python==1.2.4", 
	"pygeoip", 
	"python-dateutil", 
	"python-memcached", 
	"pytz==2013d", 
	"requests", 
	"six", 
	"slugify", 
	"termcolor", 
	"werkzeug",
	"semantic_version",
	"gitpython==0.3.2.RC1"
]

def install(install_path):
	setup_folders(install_path)
	install_erpnext(install_path)
	
	post_install(install_path)
	
def install_pre_requisites():
	global is_redhat, is_debian
	is_redhat, is_debian = validate_install()
	if is_redhat:
		install_using_yum()
	elif is_debian:
		install_using_apt()
		
	install_python_modules()
	
	print "-"*80
	print "Pre-requisites Installed"
	print "-"*80

def validate_install():
	import platform

	# check os
	operating_system = platform.system()
	print "Operating System =", operating_system
	if operating_system != "Linux":
		raise Exception, "Sorry! This installer works only for Linux based Operating Systems"
	
	# check python version
	python_version = sys.version.split(" ")[0]
	print "Python Version =", python_version
	if not (python_version and int(python_version.split(".")[0])==2 and int(python_version.split(".")[1]) >= 7):
		raise Exception, "Hey! ERPNext needs Python version to be 2.7+"
	
	# check distribution
	distribution = platform.linux_distribution()[0].lower().replace('"', '')
	print "Distribution = ", distribution
	is_redhat = distribution in ("redhat", "red hat enterprise linux server", "centos", "centos linux", "fedora")
	is_debian = distribution in ("debian", "ubuntu", "elementary os", "linuxmint")
	
	if not (is_redhat or is_debian):
		raise Exception, "Sorry! This installer works only with yum or apt-get package management"
	
	return is_redhat, is_debian
		
def install_using_yum():
	packages = "gcc MySQL-python git memcached ntp vim-enhanced screen"
	
	print "-"*80
	print "Installing Packages: (This may take some time)"
	print packages
	print "-"*80
	exec_in_shell("yum install -y %s" % packages)
	

	try:
		exec_in_shell("which mysql")
	except subprocess.CalledProcessError:
		packages = "mysql mysql-server mysql-devel"
		print "Installing Packages:", packages
		exec_in_shell("yum install -y %s" % packages)
		exec_in_shell("service mysqld restart")
		
		# set a root password post install
		global root_password
		print "Please create a password for root user of MySQL"
		root_password = (get_root_password() or "erpnext").strip()
		exec_in_shell('mysqladmin -u root password "%s"' % (root_password,))
		print "Root password set as", root_password
	
	update_config_for_redhat()
	
def update_config_for_redhat():
	import re
	
	# set to autostart on startup
	for service in ("mysqld", "memcached"):
		exec_in_shell("chkconfig --level 2345 %s on" % service)
		exec_in_shell("service %s restart" % service)
	
def install_using_apt():
	exec_in_shell("apt-get update")
	packages = "python python-setuptools python-dev build-essential python-mysqldb git memcached ntp vim screen htop"
	print "-"*80
	print "Installing Packages: (This may take some time)"
	print packages
	print "-"*80
	exec_in_shell("apt-get install -y %s" % packages)
	global root_password
	if not root_password:
		root_password = get_root_password()
	exec_in_shell("echo mysql-server mysql-server/root_password password %s | sudo debconf-set-selections" % root_password)
	exec_in_shell("echo mysql-server mysql-server/root_password_again password %s | sudo debconf-set-selections" % root_password)
	
	try:
		exec_in_shell("which mysql")
	except subprocess.CalledProcessError:
		packages = "mysql-server libmysqlclient-dev"
		print "Installing Packages:", packages
		exec_in_shell("apt-get install -y %s" % packages)
	
	update_config_for_debian()
	
def update_config_for_debian():
	for service in ("mysql",):
		exec_in_shell("service %s restart" % service)
	
def install_python_modules():
	print "-"*80
	print "Installing Python Modules: (This may take some time)"
	print "-"*80
	
	try:
		exec_in_shell("which pip2.7")	
	except subprocess.CalledProcessError:
		exec_in_shell("easy_install-2.7 pip")
	
	exec_in_shell("pip2.7 install --upgrade setuptools --no-use-wheel")
	exec_in_shell("pip2.7 install --upgrade setuptools")
	exec_in_shell("pip2.7 install {}".format(' '.join(requirements)))
	
def install_erpnext(install_path):
	print
	print "-"*80
	print "Installing ERPNext"
	print "-"*80
	
	# ask for details
	global root_password
	if not root_password:
		root_password = get_root_password()
		test_root_connection(root_password)
	
	db_name = raw_input("ERPNext Database Name: ")
	if not db_name:
		raise Exception, "Sorry! You must specify ERPNext Database Name"
	
	# setup paths
	sys.path = [".", "lib", "app"] + sys.path
	import wnf
	
	# install database, run patches, update schema
	# setup_db(install_path, root_password, db_name)
	wnf.install(db_name, root_password=root_password)

	setup_cron(install_path)
	
def get_root_password():
	# ask for root mysql password
	import getpass
	root_pwd = None
	root_pwd = getpass.getpass("MySQL Root user's Password: ")
	return root_pwd
	
def test_root_connection(root_pwd):
	out = exec_in_shell("mysql -u root %s -e 'exit'" % \
		(("-p"+root_pwd) if root_pwd else "").replace('$', '\$').replace(' ', '\ '))
	if "access denied" in out.lower():
		raise Exception("Incorrect MySQL Root user's password")
		
def setup_folders(install_path):
	os.chdir(install_path)
	app = os.path.join(install_path, "app")
	if not os.path.exists(app):
		print "Cloning erpnext"
		exec_in_shell("cd %s && git clone --branch master https://github.com/webnotes/erpnext.git app" % install_path)
		exec_in_shell("cd app && git config core.filemode false")
		if not os.path.exists(app):
			raise Exception, "Couldn't clone erpnext repository"
	
	lib = os.path.join(install_path, "lib")
	if not os.path.exists(lib):
		print "Cloning wnframework"
		exec_in_shell("cd %s && git clone --branch master https://github.com/webnotes/wnframework.git lib" % install_path)
		exec_in_shell("cd lib && git config core.filemode false")
		if not os.path.exists(lib):
			raise Exception, "Couldn't clone wnframework repository"
	
	public = os.path.join(install_path, "public")
	for p in [public, os.path.join(public, "files"), os.path.join(public, "backups"),
		os.path.join(install_path, "logs")]:
			if not os.path.exists(p):
				os.mkdir(p)
				
def setup_conf(install_path, db_name):
	import os, string, random, re

	# generate db password
	char_range = string.ascii_letters + string.digits
	db_password = "".join((random.choice(char_range) for n in xrange(16)))
	
	# make conf file
	with open(os.path.join(install_path, "lib", "conf", "conf.py"), "r") as template:
		conf = template.read()
	
	conf = re.sub("db_name.*", 'db_name = "%s"' % (db_name,), conf)
	conf = re.sub("db_password.*", 'db_password = "%s"' % (db_password,), conf)
	
	with open(os.path.join(install_path, "conf.py"), "w") as conf_file:
		conf_file.write(conf)
	
	return db_password
	
def post_install(install_path):
	pass

def exec_in_shell(cmd):
	# using Popen instead of os.system - as recommended by python docs
	import subprocess
	out = subprocess.check_output(cmd, shell=True)
	return out

def parse_args():
	parser = argparse.ArgumentParser()
	parser.add_argument('--create_user', default=False, action='store_true')
	parser.add_argument('--username', default='erpnext')
	parser.add_argument('--password', default='erpnext')
	parser.add_argument('--no_install_prerequisites', default=False, action='store_true')
	return parser.parse_args()

def create_user(username, password):
	import subprocess, pwd
	p = subprocess.Popen("useradd -m -d /home/{username} -s {shell} {username}".format(username=username, shell=os.environ.get('SHELL')).split())
	p.wait()
	p = subprocess.Popen("passwd {username}".format(username=username).split(), stdin=subprocess.PIPE)
	p.communicate('{password}\n{password}\n'.format(password=password))
	p.wait()
	return pwd.getpwnam(username).pw_uid

def setup_cron(install_path):
	erpnext_cron_entries = [
		"*/3 * * * * cd %s && python2.7 lib/wnf.py --run_scheduler >> erpnext-sch.log 2>&1" % install_path,
		"0 */6 * * * cd %s && python2.7 lib/wnf.py --backup >> erpnext-backup.log 2>&1" % install_path
		]
	for row in erpnext_cron_entries:
		try:
			existing_cron = exec_in_shell("crontab -l")
			if row not in existing_cron:
				exec_in_shell('{ crontab -l; echo "%s"; } | crontab' % row)
		except:
			exec_in_shell('echo "%s" | crontab' % row)

if __name__ == "__main__":
	args = parse_args()
	install_path = os.getcwd()
	if os.getuid() != 0 and args.create_user and not args.no_install_prequisites:
		raise Exception, "Please run this script as root"

	if args.create_user:
		uid = create_user(args.username, args.password)
		install_path = '/home/{username}/erpnext'.format(username=args.username)

	if not args.no_install_prerequisites:
		install_pre_requisites()

	if os.environ.get('SUDO_UID') and not args.create_user:
		os.setuid(int(os.environ.get('SUDO_UID')))
	
	if os.getuid() == 0 and args.create_user:
		os.setuid(uid)
		if install_path:
			os.mkdir(install_path)
	
	install(install_path=install_path)
	print
	print "-"*80
	print "Installation complete"
	print "To start the development server,"
	print "Login as {username} with password {password}".format(username=args.username, password=args.password)
	print "cd {}".format(install_path)
	print "./lib/wnf.py --serve"
	print "-"*80
	print "Open your browser and go to http://localhost:8000"
	print "Login using username = Administrator and password = admin"
