# coding=utf-8

"""
This module, models.py, will define class outlines for entities that are to be used.
"""


import sys
sys.path.append('/home/dev_usr/urbtek')


# Needed for defining database entities.
from django.db import models
# Needed for getting the current date + time.
from django.utils import timezone
# Needed for working with User models.
from django.contrib.auth.models import User
# Signals allow the Profile model to be automatically created/updated when User instances are created/updated.
from django.db.models import signals
from django.db.models.signals import post_save
from django.dispatch import receiver

from django.core.validators import MaxValueValidator, MinValueValidator
from django.core.validators import validate_comma_separated_integer_list

# Needed for auto-generating a unique primary ID field.
import uuid

import subprocess

from universal_code import sms_sender
import datetime


class Project(models.Model):
	"""
	Stores unique information between projects.
	"""
	project_name        = models.CharField(max_length=100, null=False)
	project_description = models.TextField(null=True)
	current_home_url    = models.CharField(max_length=200, null=True)


#class LoadTest(models.Model):
#	"""
#	An outline of a single load test that can be run.
#	"""


class SeleniumTest(models.Model):
	"""
	An outline of a single selenium test that can be run.
	"""
	test_name        = models.CharField(max_length=100, null=False)
	test_description = models.TextField(null=True)
	project_name     = models.CharField(max_length=100, null=False)
	unique_id        = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
	is_front_end     = models.BooleanField(default=True, null=False)

	def __unicode__(self):
		return self.unique_id


class TestSuiteRuns(models.Model):
	"""
	A specific instance of a ran test suite.
	"""
	project_name          = models.CharField(max_length=100, null=False)
	date_time_ran         = models.DateTimeField(null=False)
	specific_test_run_ids = models.TextField(null=False)


class SpecificSeleniumTestRun(models.Model):
	"""
	An instance of a single specific selenium test that was ran.
	"""
	selenium_test = models.ForeignKey(SeleniumTest, on_delete=models.CASCADE)
	run_id        = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
	run_time      = models.FloatField(null=False)
	output        = models.TextField(null=True)
	passed        = models.BooleanField(null=False)


class QuickNotes(models.Model):
	"""
	A quick note :).
	"""
	user = models.OneToOneField(User, on_delete=models.CASCADE)


class TodoTask(models.Model):
	"""
	A todo task.
	"""
	user        = models.OneToOneField(User, on_delete=models.CASCADE)
	#priority    = models.FloatField(validators=[MinValueValidator(0.0), MaxValueValidator(1.0)])
	#difficulty  = models.FloatField(validators=[MinValueValidator(0.0), MaxValueValidator(1.0)])
	#time_needed = models.FloatField(validators=)


class Profile(models.Model):
	"""
	Adding additional information to user accounts.
	"""
	# The user mapped against.
	user         = models.OneToOneField(User, on_delete=models.CASCADE)

	# Custom/additional user information.
	first_name   = models.CharField(max_length=40, null=True)
	last_name    = models.CharField(max_length=40, null=True)
	cell_number  = models.CharField(max_length=40, null=True)
	cell_carrier = models.CharField(max_length=40, default='None/Don\'t Track This')
	zip_code     = models.CharField(max_length=40, null=True)
	scc_user     = models.BooleanField(default=False)
	verified     = models.BooleanField(default=False)
	birthday     = models.DateTimeField(null=True)
	created_at   = models.DateTimeField(auto_now_add=True)
	updated_at   = models.DateTimeField(auto_now=True)

	# User permissions.
	has_admin_permissions = models.BooleanField(default=False)
	# TODO : add more permissions here...

	def update_profile_information(self, cell_number=None, cell_carrier=None, zip_code=None, birthday=None, first_name=None, last_name=None):
		if cell_number is not None:
			self.cell_number  = cell_number
		if cell_carrier is not None:
			self.cell_carrier = cell_carrier
		if zip_code is not None:
			self.zip_code     = zip_code
		if birthday is not None:
			b_text = birthday
			year  = b_text.split('/')[2]
			month = b_text.split('/')[0]
			day   = b_text.split('/')[1]

			self.birthday     = year + '-' + month + '-' + day
		if first_name is not None:
			self.first_name   = first_name
		if last_name is not None:
			self.last_name    = last_name
		self.save()

	def verify(self):
		"""This function will verify the user and set their verification date.
		:return: Void.
		"""
		print('The verify method was just called for the user : ' + self.user.email)
		self.verified = True
		self.save()


class Dividend(models.Model):
	"""
	Table containing dividend payouts.
	"""
	user             = models.ForeignKey(User, on_delete=models.CASCADE)
	payout_date      = models.DateField(null=False)
	number_of_shares = models.IntegerField(null=False)
	pay_per_share    = models.FloatField(null=False)
	share_ticker     = models.CharField(max_length=100, null=False)

	def __str__(self):
		return str(self.user) + '|' + str(self.payout_date) + '|' + str(self.number_of_shares) + '|' + str(self.pay_per_share) + '|' + str(self.share_ticker) + '|'


class ScheduledTextNotification(models.Model):
	"""
	Table containing all the scheduled text notifications.
	"""
	user            = models.ForeignKey(User, on_delete=models.CASCADE)
	unique_id       = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
	message_to_send = models.TextField(max_length=100)
	created_at      = models.DateTimeField(null=False)
	execute_at      = models.DateTimeField(null=False)
	executed        = models.BooleanField(default=False)

	def __unicode__(self):
		return self.unique_id

	def save_and_schedule_message(self):
		right_now = datetime.datetime.now()
		time_delta = datetime.datetime.combine(self.execute_at.date(), datetime.datetime.min.time()) - right_now

		send_text_message_script_path = '/home/dev_usr/urbtek/all_scripts/server_system/qa/send_text_message_after_x_seconds.sh'

		full_send_address = '"' + sms_sender.get_cell_phone_address(self.user.profile.cell_carrier, self.user.profile.cell_number) + '"'
		number_of_seconds = str(time_delta.seconds)
		message_to_send   = '"' + str(self.message_to_send) + '"'
		print('Sending a message in ' + str(number_of_seconds) + ' seconds to ' + full_send_address + ' with the contents of {' + str(self.message_to_send) + '}')

		subprocess.Popen(['sudo', 'nohup', 'bash', send_text_message_script_path, number_of_seconds, full_send_address, message_to_send, str(self.unique_id), '&'])

		self.save()

	def verify(self):
		self.executed = True
		self.save()


class SleepHours(models.Model):
	"""
	Table containing all sleep hours logged.
	"""
	user               = models.ForeignKey(User, on_delete=models.CASCADE)
	start_or_stop_time = models.DateTimeField(null=False)
	is_start_time      = models.BooleanField(null=False)
	unique_id          = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

	def __unicode__(self):
		return self.unique_id


class WorkHours(models.Model):
	"""
	Table containing all work hours logged.
	"""
	user               = models.ForeignKey(User, on_delete=models.CASCADE)
	start_or_stop_time = models.DateTimeField(null=False)
	is_start_time      = models.BooleanField(null=False)
	unique_id          = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

	def __unicode__(self):
		return self.unique_id

	def __str__(self):
		if self.is_start_time:
			return 'WorkHours start time Instance{' + str(self.start_or_stop_time) + '}'
		else:
			return 'WorkHours end time Instance{' + str(self.start_or_stop_time) + '}'


class Feedback(models.Model):
	"""
	Table containing all feedback given.
	"""
	user           = models.ForeignKey(User, on_delete=models.CASCADE)
	content        = models.TextField(null=False)
	sent_at        = models.DateTimeField(null=False)
	page_sent_from = models.CharField(max_length=200, null=False)


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
	#print('Creating a new user!')
	if created:
		Profile.objects.create(user=instance)


@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
	#print('Saving a users information!')
	instance.profile.save()
