# -*- coding: utf-8 -*-

"""
    Deployments
"""

module = request.controller
resourcename = request.function

if not settings.has_module(module):
    raise HTTP(404, body="Module disabled: %s" % module)

s3db.hrm_vars()

# -----------------------------------------------------------------------------
def index():
    """ Customisable module homepage """

    return settings.customise_home(module, alt_function="index_alt")

# -----------------------------------------------------------------------------
def index_alt():
    """
        Fallback for module homepage when not customised and
        no CMS content found (ADMINs will see CMS edit unless
        disabled globally via settings.cms.hide_index)
    """

    # Just redirect to the Mission Summary View
    s3_redirect_default(URL(f="mission", args="summary"))

# -----------------------------------------------------------------------------
def mission():
    """ RESTful CRUD Controller """

    def prep(r):
        # Configure created_on field in deploy_mission
        #created_on = r.table.created_on
        #created_on.readable = True
        #created_on.label = T("Date Created")
        #created_on.represent = lambda d: \
        #                       s3base.S3DateTime.date_represent(d, utc=True)
        if r.id:
            # Mission-specific workflows return to the profile page
            tablename = r.tablename if not r.component else r.component.tablename
            next_url = r.url(component="", method="profile", vars={})
            if r.component_name == "alert":
                alert_create_script()
                if settings.get_deploy_manual_recipients():
                    create_next = URL(f="alert", args=["[id]", "select"])
                else:
                    create_next = next_url
                s3db.configure(tablename,
                               create_next = create_next,
                               delete_next = next_url,
                               update_next = next_url,
                               )
            else:
                s3db.configure(tablename,
                               create_next = next_url,
                               delete_next = next_url,
                               update_next = next_url,
                               )
            s3.cancel = next_url
            if r.component_name == "assignment":
                member_id = r.get_vars.get("member_id", None)
                if member_id and str(member_id).isdigit():
                    # Deploy-this-member action
                    htable = s3db.hrm_human_resource
                    query = (htable.id == member_id) & \
                            (htable.deleted != True)
                    row = db(query).select(htable.id, limitby=(0, 1)).first()
                    if row:
                        field = s3db.deploy_assignment.human_resource_id
                        field.default = row.id
                        field.writable = False
                        field.comment = None
                elif r.method == "create":
                    atable = s3db.deploy_assignment
                    atable.end_date.writable = atable.end_date.readable = False
            if not r.component and r.method == "profile":
                represent = lambda d: \
                            s3base.S3DateTime.datetime_represent(d, utc=True)
                s3db.deploy_alert.modified_on.represent = represent
                s3db.deploy_response.created_on.represent = represent
                s3base.s3_trunk8(lines=1)
        else:
            # All other workflows return to the summary page
            s3.cancel = r.url(method="summary", component=None, id=0)
            if not r.component:
                status = r.get_vars.get("~.status__belongs")
                if status == "2":
                    s3.crud_strings[r.tablename]["title_list"] = T("Active Missions")
                elif status == "1":
                    s3.crud_strings[r.tablename]["title_list"] = T("Closed Missions")

        return True
    s3.prep = prep

    def postp(r, output):
        if not r.component:
            # Override mission open actions to go to the profile page
            s3_action_buttons(r,
                              deletable=True,
                              editable=True,
                              read_url=r.url(method="profile", id="[id]"),
                              update_url=r.url(method="profile", id="[id]"),
                              delete_url=r.url(method="delete", id="[id]"),
                              )
            # Override the missions list-button go to the summary page
            if isinstance(output, dict) and "buttons" in output:
                # Override standard "List" button
                buttons = output["buttons"]
                if "list_btn" in buttons and "summary_btn" in buttons:
                    buttons["list_btn"] = buttons["summary_btn"]

        elif "subtitle" in output and "rheader" in output:
            # In component CRUD views, have a subtitle after the rheader
            output["rheader"] = TAG[""](output["rheader"],
                                        H3(output["subtitle"]))

        return output
    s3.postp = postp

    return s3_rest_controller(# Remove the title if we have a component
                              # (rheader includes the title)
                              notitle = lambda r: {"title": ""} \
                                               if r.component else None,
                              rheader = s3db.deploy_rheader,
                              )

# -----------------------------------------------------------------------------
def response_message():
    """
        RESTful CRUD Controller
        - can't be called 'response' as this clobbbers web2py global!
    """

    return s3_rest_controller("deploy", "response",
                              custom_crud_buttons = {"list_btn": None},
                              )

# -----------------------------------------------------------------------------
def human_resource():
    """
        RESTful CRUD Controller
    """

    # Tweak settings for RDRT
    settings.hrm.staff_experience = True
    settings.hrm.use_skills = True
    settings.search.filter_manager = True

    # Add deploy_alert_recipient as component so that we can filter by it
    s3db.add_components("hrm_human_resource",
                        deploy_alert_recipient = "human_resource_id",
                        )

    # Filter to just Deployables
    q = FS("application.active") != None
    output = s3db.hrm_human_resource_controller(extra_filter=q)
    return output

# -----------------------------------------------------------------------------
def person():
    """
        'Members' RESTful CRUD Controller
            - used as "member profile"
            - used for Imports
    """

    # Tweak settings for RDRT
    settings.hrm.staff_experience = "experience"
    settings.hrm.vol_experience = "experience"
    settings.hrm.use_skills = True
    settings.search.filter_manager = True

    return s3db.hrm_person_controller(replace_option = None,
                                      csv_extra_fields = [
                                            # CSV column headers, so no T()
                                            dict(label="Deployable",
                                                 value="true"),
                                            # Assume volunteer if not
                                            # specified in CSV
                                            dict(label="Type",
                                                 value="volunteer"),
                                            ],
                                      csv_stylesheet = ("hrm", "person.xsl"),
                                      csv_template = ("deploy", "person"),
                                      )

# -----------------------------------------------------------------------------
def group():
    """
        Groups RESTful CRUD Controller
            - used to control membership of a group cc'd on Alerts
    """

    def prep(r):
        table = r.table
        tablename = "pr_group"
        s3db.configure(tablename,
                       deletable = False,
                       )

        if r.component:
            ctable = s3db.pr_group_membership
            ctable.group_head.readable = ctable.group_head.writable = False
            f = ctable.person_id
            settings.pr.request_dob = False
            settings.pr.request_gender = False
            f.requires = s3base.IS_ADD_PERSON_WIDGET2()
            f.widget = s3base.S3AddPersonWidget2(controller="deploy")
            list_fields = ["person_id",
                           "comments",
                           ]
            s3db.configure("pr_group_membership",
                           list_fields = list_fields,
                           )

        elif not r.id:
            # Have we got a group defined?
            ltable = s3db.org_organisation_team
            query = (table.deleted == False) & \
                    (table.system == False) & \
                    (table.group_type == 5)
            organisation_id = auth.user.organisation_id
            if organisation_id:
                left = ltable.on((ltable.group_id == table.id) & \
                                 ((ltable.organisation_id == organisation_id) | \
                                  (ltable.organisation_id == None)))
            else:
                left = None
            groups = db(query).select(table.id,
                                      ltable.organisation_id,
                                      left = left,
                                      )
            if organisation_id and len(groups) > 1:
                _channels = groups.find(lambda row: row["org_organisation_team.organisation_id"] == organisation_id)
                if not _channels:
                    _channels = groups.find(lambda row: row["org_organisation_team.organisation_id"] == None)
                record = _channels.first()
            else:
                record = groups.first()

            if record:
                record_id = record.id
                r.id = record_id
                r.resource.add_filter(table.id == record_id)
                r.method = "update"
            else:
                r.method = "create"

        return True
    s3.prep = prep

    return s3_rest_controller("pr", "group",
                              )

# -----------------------------------------------------------------------------
def application():
    """
        Custom workflow to manually create standing applications
        for deployments (for staff/volunteers)
    """

    # Tweak settings for RDRT
    settings.hrm.staff_experience = True
    settings.hrm.use_skills = True
    settings.search.filter_manager = True

    def prep(r):
        method = r.method
        if not method and r.representation != "s3json":
            r.method = method = "select"
        if method == "select":
            r.custom_action = s3db.deploy_apply
        return True
    s3.prep = prep

    if "delete" in request.args or \
       request.env.request_method == "POST" and auth.permission.format=="s3json":
        return s3_rest_controller()
    else:
        #return s3db.hrm_human_resource_controller()
        return s3_rest_controller("hrm", "human_resource")

# -----------------------------------------------------------------------------
def assignment():
    """ RESTful CRUD Controller """

    def prep(r):
        mission_date = s3db.deploy_mission.created_on
        mission_date.represent = lambda d: \
                                 s3base.S3DateTime.date_represent(d, utc=True)
        if r.record:
            table = r.resource.table
            table.mission_id.writable = False
            table.human_resource_id.writable = False

        if r.representation == "popup":
            r.resource.configure(insertable=False)

        return True
    s3.prep = prep

    def postp(r, output):
        if r.id and isinstance(output, dict):
            # Add button to Upload Appraisal
            popup = r.representation == "popup"
            record_id = r.id
            atable = s3db.hrm_appraisal
            ltable = s3db.deploy_assignment_appraisal
            query = (ltable.assignment_id == record_id) & \
                    (atable.id == ltable.appraisal_id) & \
                    (atable.deleted != True)
            appraisal = db(query).select(atable.id,
                                         limitby=(0, 1)).first()
            permit = auth.s3_has_permission
            url = None
            if appraisal and permit("update", atable, record_id=appraisal.id):
                hrtable = db.hrm_human_resource
                hr = db(hrtable.id == r.record.human_resource_id).select(hrtable.person_id,
                                                                         limitby=(0, 1)
                                                                         ).first()
                if hr:
                    get_vars = {}
                    if popup:
                        method = "update.popup"
                        refresh = get_vars.get("refresh", None)
                        if refresh:
                            get_vars["refresh"] = refresh
                        record = get_vars.get("record", None)
                        if record:
                            get_vars["record"] = record
                    else:
                        method = "update"
                    url = URL(c="deploy", f="person",
                              args=[hr.person_id, "appraisal",
                                    appraisal.id, method],
                              vars=get_vars,
                              )
            elif permit("update", r.table, record_id=record_id):
                # Currently we assume that anyone who can edit the assignment can upload the appraisal
                hrtable = db.hrm_human_resource
                hr = db(hrtable.id == r.record.human_resource_id).select(hrtable.person_id,
                                                                         limitby=(0, 1)
                                                                         ).first()
                if hr:
                    get_vars = {"mission_id": r.record.mission_id,
                                }

                    if popup:
                        method = "create.popup"
                        refresh = get_vars.get("refresh", None)
                        if refresh:
                            get_vars["refresh"] = refresh
                        record = get_vars.get("record", None)
                        if record:
                            get_vars["record"] = record
                    else:
                        method = "create"
                    url = URL(c="deploy", f="person",
                              args=[hr.person_id, "appraisal", method],
                              vars=get_vars,
                              )
            if url:
                button = s3base.S3CRUD.crud_button(T("Upload Appraisal"),
                                                   _href=url,
                                                   _class="action-btn",
                                                   )
                if popup:
                    output["items"] = button
                else:
                    s3.rfooter = button
        return output
    s3.postp = postp

    return s3_rest_controller()

# -----------------------------------------------------------------------------
def competency():
    """ RESTful CRUD controller - unfiltered version """

    return s3db.hrm_competency_controller()

# -----------------------------------------------------------------------------
def credential():
    """ RESTful CRUD controller - unfiltered version """

    return s3db.hrm_credential_controller()

# -----------------------------------------------------------------------------
def experience():
    """ Experience Controller - unfiltered version """

    return s3db.hrm_experience_controller()

# -----------------------------------------------------------------------------
def event_type():
    """ RESTful CRUD Controller """

    return s3_rest_controller("event", "event_type")