package com.capgemini.framework.teamcenter.statuating;

import com.capgemini.framework.teamcenter.ServiceDataHelper;
import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.exceptions.UnableToCreateStatusException;
import com.teamcenter.schemas.soa._2006_03.exceptions.ServiceException;
import com.teamcenter.services.strong.workflow.WorkflowService;
import com.teamcenter.services.strong.workflow._2007_06.Workflow.ReleaseStatusInput;
import com.teamcenter.services.strong.workflow._2007_06.Workflow.ReleaseStatusOption;
import com.teamcenter.services.strong.workflow._2007_06.Workflow.SetReleaseStatusResponse;
import com.teamcenter.soa.client.model.strong.ReleaseStatus;
import com.teamcenter.soa.client.model.strong.WorkspaceObject;

import java.util.Arrays;

/** This class can place a Status on a {@link WorkspaceObject}. */
public class StatusSetter {
    private final TcSession session;

    /**
     * Creates a instance that is able to create statuses.
     *
     * @param session an active teamcenter session.
     */
    public StatusSetter(final TcSession session) {
        this.session = session;
    }

    /**
     * Creates a status and places it on a {@link WorkspaceObject}.
     * @param target the target {@link WorkspaceObject}
     * @param statusName the name of the status
     * @return the created Tc {@link ReleaseStatus}
     * @throws UnableToCreateStatusException if no Status was created
     */
    public ReleaseStatus putStatus(WorkspaceObject target, String statusName) throws UnableToCreateStatusException {
        WorkspaceObject[] objects = new WorkspaceObject[] {target};
        ReleaseStatusOption[] options = new ReleaseStatusOption[] {makeReleaseStatusOption(statusName)};

        // Prepare ReleaseStatusInput
        ReleaseStatusInput[] inputArray = new ReleaseStatusInput[] {makeReleaseStatusInput(objects, options)};

        // Execute
        WorkflowService wkfService = session.getWorkflowService();
        SetReleaseStatusResponse response;
        try {
            response = wkfService.setReleaseStatus(inputArray);
        } catch (ServiceException e) {
            throw new UnableToCreateStatusException("No status has been created on target object " + target.getUid(), e);
        }
        if (ServiceDataHelper.hasErrors(response.serviceData)) {
            ServiceDataHelper.displayErrors(response.serviceData);
        }
        if (response.serviceData.sizeOfCreatedObjects() <= 0) {
            throw new UnableToCreateStatusException("No status has been created on target object " + target.getUid());
        }
        return (ReleaseStatus) response.serviceData.getCreatedObject(0);
    }

    private ReleaseStatusInput makeReleaseStatusInput(WorkspaceObject[] objects, ReleaseStatusOption[] options) {
        ReleaseStatusInput input = new ReleaseStatusInput();
        input.objects = objects == null ? new WorkspaceObject[0] : Arrays.copyOf(objects, objects.length);
        input.operations = options == null ? new ReleaseStatusOption[0] : Arrays.copyOf(options, options.length);
        return input;
    }

    private ReleaseStatusOption makeReleaseStatusOption(String statusName) {
        ReleaseStatusOption option = new ReleaseStatusOption();
        option.existingreleaseStatusTypeName = "";
        option.newReleaseStatusTypeName = statusName;
        option.operation = "Append"; // The only supported operation :'(
        return option;
    }
}
