#
# SchoolTool - common information systems platform for school administration
# Copyright (c) 2005 Shuttleworth Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
"""
Functional tests for schooltool.intervention

"""

import unittest
import os
from datetime import date

from zope.interface import Interface, implements
from zope.publisher.browser import BrowserView
from zope.security.proxy import removeSecurityProxy

from schooltool.app.browser.ftests import setup
from schooltool.app.interfaces import ISchoolToolApplication
from schooltool.contact.interfaces import IContact
from schooltool.testing.analyze import queryHTML
from schooltool.testing.functional import collect_ftests
from schooltool.testing.functional import ZCMLLayer
from schooltool.basicperson.browser.ftests.setup import addPerson as addBasicPerson


dir = os.path.abspath(os.path.dirname(__file__))
filename = os.path.join(dir, '../ftesting.zcml')

intervention_functional_layer = ZCMLLayer(filename,
                                 __name__,
                                 'intervention_functional_layer')


def logInManager():
    return setup.logIn('manager', 'schooltool')


def addPerson(first_name, last_name, username, password, groups=None, browser=None):
    """Add a person.

    If username is not specified, it will be taken to be name.lower().

    If password is not specified, it will be taken to be username + 'pwd'.
    """
    if browser is None:
        browser = logInManager()
    addBasicPerson(first_name, last_name, username, password, groups, browser)

    fillInContactInfo(username, browser=browser,
                      email='%s@example.com' % username)
    browser.open('http://localhost/persons')


def fillInContactInfo(username, browser=None, email=None, language=None):
    if browser is None:
        browser = logInManager()
    browser.open('http://localhost/persons/%s' % username)
    # TODO: other needed fields
    contact_fields = {
        'form.widgets.email': email,
        'form.widgets.language': language,
        }
    browser.getLink('Contacts').click()
    browser.getLink('Edit').click()
    for name, value in contact_fields.items():
        if value is not None:
            browser.getControl(name=name).value = value
    browser.getControl('Apply').click()


def addCourseSectionMembers(course, section, teachers, students):
    setup.addCourse(course, '2005-2006')
    setup.addSection(course, '2005-2006', 'Spring', section)
    manager = logInManager()
    manager.getLink('Manage').click()
    manager.getLink('School Years').click()
    manager.getLink('2005-2006').click()
    manager.getLink('Spring').click()
    manager.getLink('Sections').click()
    manager.getLink(section).click()
    manager.getLink('edit instructors').click()
    for teacher in teachers:
        manager.getControl(teacher).click()
    manager.getControl('Add').click()
    manager.getControl('OK').click()
    manager.getLink('edit individuals').click()
    for student in students:
        manager.getControl(student).click()
    manager.getControl('Add').click()
    manager.getControl('OK').click()


def addAdvisors(student, advisors):
    manager = logInManager()
    for advisor in advisors:
        manager.getLink('Manage').click()
        manager.getLink('Persons').click()
        manager.getLink(student).click()
        manager.getLink('Advisors').click()
        manager.getControl(name='add_item.' + advisor).value = 'checked'
        manager.getControl('Add').click()


def removeAdvisors(student, advisors):
    manager = logInManager()
    for advisor in advisors:
        manager.getLink('Manage').click()
        manager.getLink('Persons').click()
        manager.getLink(student).click()
        manager.getLink('Advisors').click()
        manager.getControl(name='remove_item.' + advisor).value = 'checked'
        manager.getControl('Remove').click()


def _checkPersonsResponsible(browser, url, persons_responsible):
    browser.open(url)
    pre_checked_xpath = '//input[@type="checkbox"][@checked="checked"]/@name'
    for fld in queryHTML(pre_checked_xpath, browser.contents):
        browser.getControl(name=fld).value = False
    all_checkboxes_xpath = '//input[@type="checkbox"]/@name'
    for person in persons_responsible:
        for fld in queryHTML(all_checkboxes_xpath, browser.contents):
            if fld.startswith('persons.' + person):
                browser.getControl(name=fld).value = True


def addMessage(browser, url, persons_responsible, body='x'):
    _checkPersonsResponsible(browser, url, persons_responsible)
    browser.getControl(name='field.body').value = body
    browser.getControl(name='UPDATE_SUBMIT').click()


def addEditGoal(browser, url, persons_responsible, values=None):
    _checkPersonsResponsible(browser, url, persons_responsible)
    if values is None:
        values = ['x', 'x', 'x', 'x', 'x', date.today()]
    browser.getControl('Presenting concerns').value = values[0]
    browser.getControl(name='field.goal').value = values[1]
    browser.getControl('Strengths').value = values[2]
    browser.getControl('Indicators').value = values[3]
    browser.getControl('Intervention').value = values[4]
    browser.getControl('Timeline').value = str(values[5])
    browser.getControl(name='UPDATE_SUBMIT').click()


class TestOnlyUpdateResponsibleView(BrowserView):

    def __call__(self):
        persons = ISchoolToolApplication(None)['persons']
        if 'add' in self.request:
            username = self.request.get('add')
            contact = IContact(persons[username])
            self.responsible.add(contact)
        elif 'remove' in self.request:
            username = self.request.get('remove')
            contact = IContact(persons[username])
            self.responsible.remove(contact)


class TestOnlyUpdateRecipientsView(TestOnlyUpdateResponsibleView):

    def __init__(self, context, request):
        super(TestOnlyUpdateRecipientsView, self).__init__(context, request)
        self.responsible = removeSecurityProxy(self.context).recipients


class TestOnlyUpdatePersonsResponsibleView(TestOnlyUpdateResponsibleView):

    def __init__(self, context, request):
        super(TestOnlyUpdatePersonsResponsibleView, self).__init__(context, request)
        self.responsible = removeSecurityProxy(self.context).persons_responsible


class ActivitiesStub(object):
    def values(self):
        worksheet1 = WorksheetStub('Worksheet1', True)
        worksheet2 = WorksheetStub('Worksheet2', False)
        return [worksheet1, worksheet2]


class IWorksheetStub(Interface):
    pass


class WorksheetStub(object):
    implements(IWorksheetStub)

    def __init__(self, title, deployed):
        self.title = title
        self.deployed = deployed


class WorksheetAbsoluteURLStub(object):
    def __init__(self, worksheet, request):
        self.worksheet = worksheet

    def __call__(self):
        return self.worksheet.title


def getSectionIndependentActivities(section):
    if section.title == 'special title':
        return ActivitiesStub()


def test_suite():
    return collect_ftests(layer=intervention_functional_layer)


if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')

