package com.atlassian.confluence.extra.workflow;

import com.atlassian.confluence.core.ContentPermission;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: Tomd
 * Date: 3/05/2005
 * Time: 11:45:35
 * To change this template use File | Settings | File Templates.
 */
public class WorkflowManager
{
    private static Map types = Collections.synchronizedMap(new HashMap());

    static
    {
        String reviewWarning = "{warning}This content is under review.{warning}";
        State inprogress = new State("test", "In Progress", "In Progress",reviewWarning);
        State readyToReview = new State("test", "Ready for review", "Ready for review",reviewWarning);
        State accepted = new State("test", "Accepted", "Accepted",null);
        State rejected = new State("test", "Rejected", "Rejected",reviewWarning);
        State[] states = new State[]{inprogress, readyToReview, accepted, rejected};
        Operation[] ops = new Operation[]{
            new DefaultOperation(new Condition[]{new StateSetCondition(new State[]{inprogress}), new GroupSetCondition(new String[]{"writer"})}, "completed", "Submit for Review"),
            new DefaultOperation(new Condition[]{new StateSetCondition(new State[]{readyToReview}), new GroupSetCondition(new String[]{"reviewer"}), new UserNotAssignedAs("author")}, "accept", "Accept"),
            new DefaultOperation(new Condition[]{new StateSetCondition(new State[]{readyToReview}), new GroupSetCondition(new String[]{"reviewer"}),new UserNotAssignedAs("author")}, "reject", "Reject"),
            new DefaultOperation(new Condition[]{new StateSetCondition(new State[]{inprogress, rejected}), new GroupSetCondition(new String[]{"writer"}),}, "withdraw", "Withdraw Changes"),
        };
        String[] groups = new String[]{"writer", "reviewer", "confluence-administrators"};
        Trigger[] triggers = new Trigger[]{
            new SingleEventTrigger("init",
                    new Action[]{
                        new StateChangeAction(inprogress),
                        new TagCurrentVersionAction("accepted"),
                        new RestrictAccessToGroupAction(new ContentPermission(ContentPermission.EDIT_PERMISSION, "writer")),
                        new RestrictAccessToGroupAction(new ContentPermission(ContentPermission.VIEW_PERMISSION, "confluence-users")),
                        new SingleAssignmentAction("author")
                    }),
            new SingleEventTrigger("completed",
                    new Action[]{
                        new StateChangeAction(readyToReview)
                    }),
            new SingleEventTrigger("accept",
                    new Action[]{
                        new StateChangeAction(accepted),
                        new TagCurrentVersionAction("accepted"),
                        new RemoveSingleAssignmentAction("author")
                    }),
            new SingleEventTrigger("reject",
                    new Action[]{
                        new StateChangeAction(rejected)
                    }),
            new SingleEventTrigger("withdraw",
                    new Action[]{
                        new StateChangeAction(accepted),
                        new ReplaceCurrentVersionWithTaggedVersion("accepted"),
                        new RemoveSingleAssignmentAction("author")
                    }),
            new SingleEventTrigger(PageEditOperation.OPERATION_NAME,
                    new Action[]{
                        new StateChangeAction(inprogress),
                        new SingleAssignmentAction("author")
                    }),
        };
        ActionType[] actionTypes = new ActionType[] {
            new ActionType(RemoveSingleAssignmentAction.class, "Remove an assignment to a page"),
            new ActionType(ReplaceCurrentVersionWithTaggedVersion.class, "Replace the current version of a page with a tagged version"),
            new ActionType(RestrictAccessToGroupAction.class, "Restrict access to the page to a group"),
            new ActionType(StateChangeAction.class, "Change the workflow state of the page"),
            new ActionType(TagCurrentVersionAction.class, "Tag the current version of the page")
        };
        TriggerType[] triggerTypes = new TriggerType[] {
            new TriggerType(SingleEventTrigger.class, "Listen for a single workflow step")
        };
        registerType(new DefaultWorkflowType("test", "Page Review", states, ops, triggers, groups, new String[] {"author"},actionTypes,triggerTypes));
    }

    public static WorkflowType findType(String workflowType)
    {
        return (WorkflowType) types.get(workflowType);
    }

    public static void registerType(WorkflowType type)
    {
        types.put(type.getName(), type);
    }
}
