
from datetime import datetime
from django.utils import timezone  # FIXME what defs are actually used?
import sys
import stat
import os 
from subprocess import check_output, CalledProcessError 
#import pdb


# to be done only once to update existing users that signed up before
# the integration with Stripe

from django.contrib.auth.models import User
from django.conf import settings
def init_stripe_customer_objects():
  try:
    sys.path.insert(1, '/var/www/mysite/ideatree/')
    from .models import UserProfile
    import stripe
    for actUser in User.objects.filter(is_active=True):
      nonStripeUserProfile = UserProfile.objects.filter(stripecustomerid='',user=actUser)  # will return only one
      if nonStripeUserProfile.count() > 1:
        raise Exception("Database returned more than one profile for one canonical User.")
      elif nonStripeUserProfile.count() == 0:
        print("Skipping User id " + str(actUser.id) + " that already has a stripe customer id in his corresponding UserProfile.")
      elif nonStripeUserProfile.count() == 1:
        stripe.api_key = settings.STRIPE_SECRET_KEY
        stripe_customer_object = stripe.Customer.create(
          email = actUser.email,
          description="IdeaTree Premium account customer",
        )
        nonStripeUserProfile.update(stripecustomerid=stripe_customer_object.id)
        print("Saved: for User: " + str(actUser.id) + " stripe customer id: " + stripe_customer_object.id + " in his corresponding UserProfile.")
    print("Success")
    return(True)
  except stripe.error.InvalidRequestError as err:
    print(str(err))
    return(False)
  except Exception as err:
    print(str(err))
    return(False)


def truncateStr(string, toLength):
  return ((string[:toLength-2] + '..') if len(string) > toLength else string)


class Struct:
    def __init__(self, **entries):
        self.__dict__.update(entries)


def doWSGIPermissions(filepath, mask=False):
    try:
      if not mask:
        mask = stat.S_IRWXU
      # FIXME: save these two as namespaced variables rather than call them each time.
      userId = int(check_output(['id -u wsgiuser'],shell=True))
      groupId = int(check_output(['id -u www-data'],shell=True))

      os.chmod(filepath, mask)
      os.chown(filepath,userId, groupId)
    except CalledProcessError as err:
        writeErr(err)
        raise Exception(err) 
    except OSError as err:
        writeErr(err)
        raise Exception(err) 
    except Exception as err:
        writeErr(err)
        return HttpResponse(str(err), status=406)   

       



# Extract values from an arbitrary key in deeply nested JSON.
# NOTE: from https://hackersandslackers.com/extract-data-from-complex-json-python/
def extract_values(obj, key):
  # Pull all values of specified key from nested JSON.
  arr = []

  def extract(obj, arr, key):
  # Recursively search for values of key in JSON tree.
    if isinstance(obj, dict):
      for k, v in obj.items():
        if isinstance(v, (dict, list)):
          extract(v, arr, key)
        elif k == key:
          arr.append(v)
    elif isinstance(obj, list):
      for item in obj:
        extract(item, arr, key)
    return arr

  results = extract(obj, arr, key)
  return results



# For converting bytes to strings for streaming to stderr, as when writing to apache log files when using wsgi.
def writeErr(line):
  try:
    line = line.decode() # if it's bytes, convert to string
  except (UnicodeDecodeError, AttributeError):
    pass
  print(line,file=sys.stderr)



# From https://github.com/django/django/blob/master/django/template/defaultfilters.py
def addslashes(value):
  """
  Add slashes before quotes. Useful for escaping strings in CSV, for
  example. Less useful for escaping JavaScript; use the ``escapejs``
  filter instead.
  """
  return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'")

 

def tostr(s):
	if not s:
		return ''
	return str(s)


def rStrChop(thestring, ending):
	if thestring.endswith(ending):
		return thestring[:-len(ending)]
	return thestring



# return current time in milliseconds
def millisNow(offsetSeconds=0, decimalPoints=0):
	# See https://julien.danjou.info/blog/2015/python-and-timezones
	# Not as easy as it looks.  See:
	# http://stackoverflow.com/questions/5998245/get-current-time-in-milliseconds-in-python#comment46689980_21858377
	# https://docs.python.org/3.4/library/datetime.html?highlight=datetime#datetime.datetime
	dateTimeNow = datetime.now(timezone.utc) - datetime(1970, 1, 1, tzinfo=timezone.utc)
	ms = round((dateTimeNow.days * 24 * 60 * 60 + (dateTimeNow.seconds + offsetSeconds)) * 1000 + dateTimeNow.microseconds / 1000.0, decimalPoints)
	if not decimalPoints:
		return (int(ms))
	return (ms)


# FIXME: remove
#from html.parser import HTMLParser
#
#class MLStripper(HTMLParser):
#	def __init__(self):
#		super().__init__()
#		self.reset()
#		self.strict = False
#		self.convert_charrefs= True
#		self.fed = []
#
#	def handle_data(self, d):
#		self.fed.append(d)
#	def get_data(self):
#		return ''.join(self.fed)
#
#
#def strip_tags(html):
#	s = MLStripper()
#	s.feed(html)
#	return s.get_data()


