##############################################################################
# Copyright (c) 2004-2005 Black Rock City, LLC
# Copyright (c) 2004-2005 ObjectRealms, LLC
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
##############################################################################
"""
$Id: $
"""
from Testing import ZopeTestCase
from OFS.ObjectManager import BadRequestException

try:
    from Products.pythonproducts import pythonproducts
except ImportError:
    from Products.Five import pythonproducts
    pythonproducts.Zope2 = ZopeTestCase.Zope2
    
from Products.Five import zcml

from Products.TeamSpace.config import MEMBER_CATALOG

import dummy
from Products.PloneTestCase import PloneTestCase
from Products.CMFCore.utils import getToolByName

from Products.CMFPlone.utils import _createObjectByType

from AccessControl.SecurityManagement import newSecurityManager
from Products.Archetypes.Extensions.Install import install as install_archetypes

from Products.PloneTestCase.setup import portal_name
from Products.PloneTestCase.setup import portal_owner
default_user = 'unittest_admin'

ZopeTestCase.installProduct('ZCatalog')
ZopeTestCase.installProduct('MailHost', quiet=1)
ZopeTestCase.installProduct('CMFCore')
ZopeTestCase.installProduct('CMFDefault')
ZopeTestCase.installProduct('DCWorkflow')
ZopeTestCase.installProduct('CMFActionIcons')
ZopeTestCase.installProduct('CMFQuickInstallerTool')
ZopeTestCase.installProduct('CMFFormController')
ZopeTestCase.installProduct('ZCTextIndex')
ZopeTestCase.installProduct('CMFPlone')
ZopeTestCase.installProduct('Archetypes')
ZopeTestCase.installProduct('PortalTransforms')
ZopeTestCase.installProduct('MimetypesRegistry')
ZopeTestCase.installProduct('membrane')
ZopeTestCase.installProduct('pythonproducts')
ZopeTestCase.installProduct('TeamSpace')

PloneTestCase.setupPloneSite(portal_name)

# Make some members, roles
members = ['member_%s' %(x+1) for x in range(10)]

member_roles = ['Member']
manager_roles = ['Member', 'Manager']
reviewer_roles = ['Reviewer', 'Member']

makegroup = lambda members, status, roles: [((member, status), roles) for member in members]

member_map_1 =     makegroup(members[:1],  'activated', member_roles) # solo team
member_map_2 =     makegroup(members[:2],  'activated', member_roles) # team with inclusion
manager_map_1 =    makegroup(members[3:4], 'activated', manager_roles)
manager_map_2 =    makegroup(members[3:5], 'activated', manager_roles)
notmember = members[2]

"""

MEMBER KEY:
M: manager
m: member
R: reviewer
N: nonmember

[teams>]    TEAM_1  TEAM_2  TEAM_3
member_1    m       m
member_2            m
member_3                            < member_3 is the token nonmember
member_4    m Ma    m Ma
member_5            m Ma
"""

from TeamDataBag import TeamDataBag

# create a couple of teams with managers

t1_map = member_map_1 + manager_map_1
t2_map = member_map_2 + manager_map_2

TEAM_1 = TeamDataBag('team_1', t1_map)
TEAM_2 = TeamDataBag('team_2', t2_map)

userid_zcml = """
<configure xmlns="http://namespaces.zope.org/zope">

  <adapter for="Products.TeamSpace.tests.dummy.Member"
           provides="Products.membrane.interfaces.IUserRelated"
           factory="Products.membrane.examples.useridprovider.UserIdProvider"
           />

</configure>
"""

class TeamTestCase(PloneTestCase.PloneTestCase):

    def installProducts(self, products=[]):
        self.portal.portal_quickinstaller.installProducts(products=products,
                                                          stoponerror=1)

    def afterSetUp( self ):
        # have to manually trigger pythonproducts patches
        try:
            pythonproducts.applyPatches(ZopeTestCase.Zope2.app())
        except TypeError:
            # Five's version of pythonproducts gets app from its own namespace
            pythonproducts.applyPatches()

        self.loginAsPortalOwner()
        install_archetypes(self.portal)

        zcml.load_string(userid_zcml)
        portal_setup = getToolByName(self.portal, 'portal_setup')
        portal_setup.setImportContext('profile-membrane:default')
        portal_setup.runAllImportSteps()
        member_catalog = getToolByName(self.portal, MEMBER_CATALOG)
        member_catalog.registerMembraneType(dummy.Member.portal_type)

        self.installProducts(products=['TeamSpace'])
        self._refreshSkinData()
        self.tool = self.portal.portal_teams
        self.uf = self.portal.acl_users
        self.folder = self.portal.Members.test_user_1_

    def beforeTearDown(self):
        # have to manually trigger pythonproducts patches
        try:
            pythonproducts.removePatches(ZopeTestCase.Zope2.app())
        except TypeError:
            # Five's version of pythonproducts gets app from its own namespace
            pythonproducts.removePatches()


    def addAndPopulateTeam(self, teamData, add_roles=0):
        pm_tool = self.portal.portal_membership
        wf_tool = self.portal.portal_workflow
        acl_users = self.portal.acl_users

        self.loginAsPortalOwner()

        for m in teamData.getMemberIds():
            if not hasattr(self.portal, m):
                obj = _createObjectByType('Member', self.portal,
                                          m, email='%s@example.com'%m)

        tmtool = self.tool
        tmtool.invokeFactory("Team", teamData.id)
        team = tmtool.getTeamById(teamData.id)
        for member_id in teamData.getMemberIds():
            team.addMember(member_id)

        # add roles to memberships
        memberships = [(x.id, x) for x in team.getMemberships()]
        roles = teamData.rolesDict()
        for m_id, m_ship in memberships:
            m_ship.editTeamRoles(roles[m_id])

    def setStatusForMembership(self, teamData):
        wf_tool = self.portal.portal_workflow
        team = self.tool.getTeamById(teamData.id)
        m_ships  =  dict([ ( x.id, x ) for x  in team.getMemberships()])
        m_stati = teamData.statusDict()

        setStatus = wf_tool.setStatusOf
        getStatus = wf_tool.getStatusOf

        ### is there a multiple workflow case here?
        ### kt - potentially yes, we try to defer to a set of states applicable
        ### to any workflow and an explicit workflow id attribute on the membership
        ### to identify a workflow
        #workflowId = lambda x: wf_tool.getWorkflowsFor(x)[0]

        for m_id in m_stati.keys():
            m_ship = m_ships[m_id]
            wf_tool.doActionFor(m_ship, 'activate')
