# -*- coding: utf-8 -*-
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.contrib.auth.models import User, Permission
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth import authenticate, login, logout
from users.models import *

import json

## Login Form
# POST method
# Key: username, password, saveid
def Login_site(request):
	if request.method == "POST":
		# if username or password is null
		if not request.POST['username'] or not request.POST['password']:
			return HttpResponseRedirect('/login_site')
			
		try:
			saveid = request.POST['saveid'] == 'on'
		except KeyError:
			saveid = False
		
		user = authenticate(username=request.POST['username'], password=request.POST['password'])
		
		if user is None:
			return HttpResponseRedirect('/login_site')
			
		if user.is_active:
			login(request, user)
			# Redirect to a success page.			
			if saveid:
				request.session.set_expiry(datetime.timedelta(days=30))
			else:
				request.session.set_expiry(0)
			return HttpResponseRedirect('/viewer')		
		else:
			# Return a 'disabled account' error message
			response = {'success':False, 'reason':'InvalidIdPasswd'}
			return HttpResponse(json.dumps(response))
	else:
		if request.user.is_anonymous():
			variables = {}
			return render_to_response('pages/login.html', RequestContext(request, variables))
		else:
			return HttpResponseRedirect('/viewer')

## Login Form
# POST method
# Key: username, password, saveid
# Return: True or False
@csrf_exempt
def Login_ajax(request):
	if request.method == "POST":
		# if username or password is null
		if not request.POST['username'] or not request.POST['password']:
			response = {'success':False, 'reason':'InsufficientParameter'}
			return HttpResponse(json.dumps(response))
			
		try:
			saveid = request.POST['saveid'] == 'on'
		except KeyError:
			saveid = False
		
		user = authenticate(username=request.POST['username'], password=request.POST['password'])
		
		if user is None:
			response = {'success':False, 'reason':'InvalidIdPasswd'}
			return HttpResponse(json.dumps(response))
			
		if user.is_active:
			login(request, user)
			# Redirect to a success page.			
			if saveid:
				request.session.set_expiry(datetime.timedelta(days=30))
			else:
				request.session.set_expiry(0)
			
			variables = {'success': True, 'id': user.id, 'permission': user.userprofile.userType}
			return HttpResponse(json.dumps(variables), mimetype='application/json')			
		else:
			# Return a 'disabled account' error message
			response = {'success':False, 'reason':'InvalidIdPasswd'}
			return HttpResponse(json.dumps(response))
	else:
		raise Http404 
		
## Logout Form
# POST method
# Return: main page path
def Logout(request):	
	if request.method == "POST":		
		logout(request)
		# Redirect to a success page.
		redirect_address = '/'
		if request.POST.has_key('next'):
			redirect_address = request.POST['next']
		return HttpResponseRedirect(redirect_address)
	else:
		logout(request)
		redirect_address = '/'
		if request.GET.has_key('next'):
			redirect_address = request.GET['next']
		return HttpResponseRedirect(redirect_address)

## get User list
# Return: xml - User list
def getUserList(request):
	valid = request.POST['Visible'].lower() == 'true' if request.POST.has_key('Visible') else True
	userList = User.objects.filter(userprofile__valid = valid)
	
	variables = {'userList': userList}
	return render_to_response('xml/userlist.xml', RequestContext(request, variables))

## Get User Info
# GET method
# Key: userId[uid]
# Return: username, profileName, userFabricCount
def getUserInfo(request):
	try:
		userId = request.POST['uid']
	except KeyError:
		raise Http404
	
	try:
		user = User.objects.get(id=userId)
		variables = {
			'success': True,
			'username': user.username,
			'profileName': user.userprofile.name,
			'userFabricCount': user.userprofile.userFabricCount,
			'userType': user.userprofile.userType,
			'clientGroupId': user.userprofile.client_group.id if user.userprofile.client_group else 0,
		}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	except ObjectDoesNotExist:
		variables = {'success': False, 'reason': 'DoesNotExist'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')

## create User(Create or Update)
# POST method
# Key: type, userId, passwd, userName, userFabricCount
# type: create, update
def createUser(request):		
	try:
		username = request.POST['username']
		passwd = request.POST['passwd']
		profileName = request.POST['profileName']
		userFabricCount = int(request.POST['userFabricCount'])
		userType = int(request.POST['userType'])
		clientGroupId = int(request.POST['cgid'])
	except:
		response = {'success':False, 'reason':'InsufficientParameter'}
		return HttpResponse(json.dumps(response), mimetype='application/json')
	
	# check duplicated name
	if User.objects.filter(username = username).exists():
		response = {'success': False, 'reason': 'NameAlreadyExists'}
		return HttpResponse(json.dumps(response), mimetype='application/json')
	
	try:
		clientGroup = ClientGroup.objects.get(id = clientGroupId)
	except ObjectDoesNotExist:
		clientGroup = None
	
	try:
		user = User.objects.create_user(username=username, password=passwd)
		if userType == 3:
			user.is_staff = True
		else:
			user.is_staff = False
		user.save()
		user.userprofile.name = profileName
		user.userprofile.userFabricCount = userFabricCount
		user.userprofile.userType = userType
		user.userprofile.client_group = clientGroup
		user.userprofile.save()
		
		response = {'success': True, 'id': user.id}
		return HttpResponse(json.dumps(response), mimetype='application/json')
	except Exception as e:
		user.delete()
		response = {'success':False, 'reason':e.__class__.__name__}
		return HttpResponse(json.dumps(response), mimetype='application/json')

## modify User
# Return: json - {success: True/False}
def modifyUser(request):
	try:
		userId = int(request.POST['uid'])
		userType = int(request.POST['userType'])
		clientGroupId = int(request.POST['cgid'])
	except:
		raise Http404
	
	try:
		user = User.objects.get(id = userId)
	except ObjectDoesNotExist:
		variables = {'success': False, 'reason': 'DoesNotExist'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
		
	changed = False
	failReason = ''
	
	if request.POST.has_key('username') and request.POST['username']:
		username = request.POST['username']
		
		if username == user.username:
			pass
		elif User.objects.filter(username = username).exists():
			failReason += 'NameAlreadyExists;'
		else:
			user.username = username
			changed = True
	
	if request.POST.has_key('passwd') and request.POST['passwd']:
		passwd = request.POST['passwd']
		user.set_password(passwd)
		changed = True
	
	if request.POST.has_key('profileName') and request.POST['profileName']:
		profileName = request.POST['profileName']
		
		if not profileName == user.userprofile.name:
			user.userprofile.name = profileName
			changed = True
	
	if request.POST.has_key('userFabricCount') and request.POST['userFabricCount']:
		try:
			userFabricCount = int(request.POST['userFabricCount'])
		except ValueError:
			raise Http404
		if userFabricCount != user.userprofile.userFabricCount:
			userFabricCount = userFabricCount if userFabricCount > 0 else 0
			user.userprofile.userFabricCount = userFabricCount
			changed = True
	
	if userType != user.userprofile.userType:
		if user == request.user:
			failReason += 'ItIsMyself;'
		else:
			user.userprofile.userType = userType
			if userType == 3:
				user.is_staff = True
			else:
				user.is_staff = False
			changed = True
	
	try:
		clientGroup = ClientGroup.objects.get(id = clientGroupId)
	except ObjectDoesNotExist:
		clientGroup = None
	
	if clientGroup != user.userprofile.client_group:
		user.userprofile.client_group = clientGroup
		changed = True
	
	if len(failReason) > 0:
		variables = {'success': False, 'reason': failReason}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	if changed:
		user.userprofile.save()
		user.save()
	
		variables = {'success': True}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	else:
		variables = {'success': False, 'reason': 'NoChanges'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
## delete User
# POST method
# Key: userId[uid]
# delete User and Fabric, Files for User
def deleteUser(request):
	try:
		userId = int(request.POST['uid'])
	except:
		raise Http404
	
	try:
		user = User.objects.get(id = userId)
	except ObjectDoesNotExist:
		variables = {'success': False, 'reason': 'DoesNotExist'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	if user == request.user:
		variables = {'success': False, 'reason': 'ItIsMyself'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	user.delete()
	
	variables = {'success': True}
	return HttpResponse(json.dumps(variables), mimetype='application/json')

def getClientGroupList(request):
	clientGroupList = ClientGroup.objects.all()
	
	variables = {'clientGroupList': clientGroupList}
	return render_to_response('xml/clientgrouplist.xml', RequestContext(request, variables))

def createClientGroup(request):		
	try:
		name = request.POST['name']
		if not name:
			raise Exception
	except:
		response = {'success':False, 'reason':'InsufficientParameter'}
		return HttpResponse(json.dumps(response), mimetype='application/json')
	
	# check duplicated name
	if ClientGroup.objects.filter(name = name).exists():
		response = {'success': False, 'reason': 'NameAlreadyExists'}
		return HttpResponse(json.dumps(response), mimetype='application/json')
	
	try:
		clientGroup = ClientGroup(name = name)
		clientGroup.save()
		
		response = {'success': True, 'id': clientGroup.id}
		return HttpResponse(json.dumps(response), mimetype='application/json')
	except Exception as e:
		clientGroup.delete()
		response = {'success':False, 'reason':e.__class__.__name__}
		return HttpResponse(json.dumps(response), mimetype='application/json')

def modifyClientGroup(request):
	try:
		clientGroupId = int(request.POST['cgid'])
		name = request.POST['name']
		if not name:
			raise Exception
	except:
		raise Http404
	
	try:
		clientGroup = ClientGroup.objects.get(id = clientGroupId)
	except ObjectDoesNotExist:
		variables = {'success': False, 'reason': 'DoesNotExist'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	if clientGroup.name != name:
		clientGroup.name = name
		clientGroup.save()
	
		variables = {'success': True}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	else:
		variables = {'success': False, 'reason': 'NoChanges'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')

def deleteClientGroup(request):
	try:
		clientGroupId = int(request.POST['cgid'])
	except:
		raise Http404
	
	try:
		clientGroup = ClientGroup.objects.get(id = clientGroupId)
	except ObjectDoesNotExist:
		variables = {'success': False, 'reason': 'DoesNotExist'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	if clientGroup.userprofile_set.exists():
		variables = {'success': False, 'reason': 'HasUserSet'}
		return HttpResponse(json.dumps(variables), mimetype='application/json')
	
	clientGroup.delete()
	
	variables = {'success': True}
	return HttpResponse(json.dumps(variables), mimetype='application/json')