# Standard imports
import unittest
import sys
import os
from datetime import datetime, timedelta
import logging

# Our imports
from emission.core.get_database import get_db, get_client_db, get_profile_db, get_uuid_db, get_pending_signup_db, get_section_db
from emission.core.wrapper.client import Client
from emission.tests import common
from emission.core.wrapper.user import User

import emission.tests.common as etc

class TestClient(unittest.TestCase):
  def setUp(self):
    # Make sure we start with a clean slate every time
    self.serverName = 'localhost'
    common.dropAllCollections(get_db())
    logging.info("After setup, client count = %d, profile count = %d, uuid count = %d" % 
      (get_client_db().find().count(), get_profile_db().count(), get_uuid_db().count()))
    common.loadTable(self.serverName, "Stage_Modes", "emission/tests/data/modes.json")
    
  def testInitClient(self):
    emptyClient = Client("testclient")
    self.assertEqual(emptyClient.clientName, "testclient")
    self.assertEqual(emptyClient.settings_filename, "emission/clients/testclient/settings.json")
    self.assertEqual(emptyClient.clientJSON, None)
    self.assertEqual(emptyClient.startDatetime, None)
    self.assertEqual(emptyClient.endDatetime, None)

  def testIsEmptyClientActive(self):
    emptyClient = Client("testclient")
    self.assertFalse(emptyClient.isActive(datetime.now()))

  def updateWithTestSettings(self, client, fileName):
    client.settings_filename = fileName
    client.update(createKey = True)

  def testCreateClient(self):
    client = Client("testclient")
    client.update(createKey = False)
    self.assertEqual(client.startDatetime, datetime(2014, 10, 13))
    self.assertEqual(client.endDatetime, datetime(2016, 12, 25))
    self.assertEqual(client.isActive(datetime(2014, 11, 7)), True)
    self.assertEqual(client.getDates()[0], datetime(2014, 10, 13))
    self.assertEqual(client.getDates()[1], datetime(2016, 12, 25))

    # Reset the times in the client so that it will show as active and we will
    # get a valid set of settings    
    common.makeValid(client)
    self.assertEqual(client.isActive(datetime.now()), True)
    self.assertNotEqual(client.getSettings(), None)
    self.assertNotEqual(client.getSettings(), {})

    print client.getSettings()
    self.assertNotEqual(client.getSettings()['result_url'], None)

  def testUpdateClient(self):
    client = Client("testclient")
    self.updateWithTestSettings(client, "emission/tests/coreTests/wrapperTests/testclient/testclient_settings_update.json")

    self.assertEqual(client.startDatetime, datetime(2015, 01, 13))
    self.assertEqual(client.endDatetime, datetime(2015, 04, 25))
    self.assertEqual(client.getDates()[0], datetime(2015, 01, 13))
    self.assertEqual(client.getDates()[1], datetime(2015, 04, 25))

  def testCallMethod(self):
    client = Client("testclient")
    client.update(createKey = False)
    result = client.callMethod("classifiedCount", {'user': 'fake_user'})
    self.assertEqual(result, {'count': 0})

  def testPreRegisterNewUser(self):
    client = Client("testclient")
    client.update(createKey = False)
    common.makeValid(client)
    (resultPre, resultReg) = client.preRegister("this_is_the_super_secret_id", "fake@fake.com")
    self.assertEqual(resultPre, 1)
    self.assertEqual(resultReg, 0)

  def testPreRegisterExistingUser(self):
    user = User.register("fake@fake.com")

    client = Client("testclient")
    client.update(createKey = False)
    common.makeValid(client)
    (resultPre, resultReg) = client.preRegister("this_is_the_super_secret_id", "fake@fake.com")
    self.assertEqual(resultPre, 0)
    self.assertEqual(resultReg, 1)

    self.assertEqual(user.getStudy(), ['testclient'])
    pendingRegs = Client.getPendingClientRegs("fake@fake.com")
    self.assertEqual(pendingRegs, [])

  def testPreRegisterFail(self):
    client = Client("testclient")
    client.update(createKey = False)
    common.makeValid(client)
    (resultPre, resultReg) = client.preRegister("this_is_the_super_secret_id", "fake@fake.com")
    self.assertEqual(resultPre, 1)
    self.assertEqual(resultReg, 0)

    pendingRegs = Client.getPendingClientRegs("fake@fake.com")
    self.assertEqual(pendingRegs, ["testclient"])

  def testPendingClientRegs(self):
    fakeEmail = "fake@fake.com"

    client = Client("testclient")
    client.update(createKey = False)
    common.makeValid(client)
    (resultPre, resultReg) = client.preRegister("this_is_the_super_secret_id", fakeEmail)
    studyList = Client.getPendingClientRegs(fakeEmail)
    self.assertEqual(studyList, ["testclient"])
   
    brokenStudyList = Client.getPendingClientRegs("bake@fake.com")
    self.assertEqual(brokenStudyList, [])

  def testPendingClientRegsDelete(self):
    fakeEmail = "fake@fake.com"

    client = Client("testclient")
    client.update(createKey = False)
    common.makeValid(client)
    (resultPre, resultReg) = client.preRegister("this_is_the_super_secret_id", fakeEmail)
    studyList = Client.getPendingClientRegs(fakeEmail)
    self.assertEqual(studyList, ["testclient"])
  
    Client.deletePendingClientRegs(fakeEmail) 
    afterDelList = Client.getPendingClientRegs(fakeEmail)
    self.assertEqual(afterDelList, [])

  def testGetSectionFilter(self):
    fakeEmail = "fake@fake.com"

    client = Client("testclient")
    client.update(createKey = False)