package com.capgemini.reports.definition.r15r16r17reports.r15r17reports.r15report;

import com.capgemini.framework.common.FileHelper;
import com.capgemini.framework.common.SettingsHelper;
import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.exceptions.KurtException;
import com.capgemini.framework.teamcenter.object.pom.status.StatusEnum;
import com.capgemini.framework.teamcenter.object.types.SnecmaObjectTypes;
import com.capgemini.framework.teamcenter.policies.PolicyLocation;
import com.capgemini.framework.teamcenter.queries.saved.modelobject.ItemQuery;
import com.capgemini.reports.database.javabean.DbReport;
import com.capgemini.reports.exceptions.NotFoundException;
import com.capgemini.reports.execution.actions.AbstractPostExecutionStep;
import com.capgemini.reports.execution.actions.ondataset.CreateDatasetAction;
import com.capgemini.reports.execution.actions.ondataset.DestroyRelationshipsAction;
import com.capgemini.reports.execution.actions.ondataset.LinkFicheArticleAction;
import com.capgemini.reports.execution.actions.ondataset.SetStatusAction;
import com.teamcenter.services.loose.core._2006_03.FileManagement.GetDatasetWriteTicketsInputData;
import com.teamcenter.soa.client.model.strong.Item;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.List;

/**
 * This action can be triggered upon report completion. Once triggered, it will:
 * <ol>
 * <li>Rename the document</li>
 * <li>Upload the created report to a dataset</li>
 * <li>Attach the dataset to the Part</li>
 * <li>Set a <code>Frozen</code> status on the dataset</li>
 * </ol>
 */
@Slf4j
@EqualsAndHashCode(callSuper = true)
public class AttachDatasetR15Action extends AbstractPostExecutionStep<ExecutionR15, Void> {
    private static final long serialVersionUID = 5891187265385234600L;

    private static final String OUTPUT_FOLDER = SettingsHelper.getReportLocation();
    private static final PolicyLocation POLICY_XML_DATASET = PolicyLocation.make("R15_policy_wkf", "/xml/policies/r15report/R15_policy_wkf.xml");

    /**
     * Creates an instance.
     */
    public AttachDatasetR15Action() {
        super(ExecutionR15.class);
    }

    private static Item getItem(final TcSession session, String targetID) throws NotFoundException {
        List<Item> results = new ItemQuery(session).searchID(targetID).findAll();

        for(Item currentResult : results){
            if(SnecmaObjectTypes.isPart(currentResult.getTypeObject().getName())){
                return currentResult;
            }
        }

        if (results.isEmpty()) {
            throw new NotFoundException("Could not find the original part " + targetID);
        } else {
            throw new NotFoundException(targetID + " part not found other type found instead");
        }

    }

    @Override
    public Void performPostActionOnReport(final TcSession session, final ExecutionR15 report, final DbReport theExecutingReport,
                                          final String fileNameWithExtension) throws KurtException {
        session.setObjectPropPolicy(POLICY_XML_DATASET);

        // Prepare naming & Make a copy with the correct name
        log.debug("Workflow launch: Beginning file copy");
        File fileCopy = copyFile(report.getDatasetFileNameWithExtension(), report.getOriginalDatasetFileNameWithExtension());

        // Obtain the Part
        String targetID = report.getItemId();
        Item target = getItem(session, targetID);

        // Detect & destroy conflicting datasets on the part, if any
        String datasetName = report.getDatasetName();
        log.debug("Workflow launch: Destroying previous datasets...");
        DestroyRelationshipsAction.destroyConflictingDatasets(session, datasetName, targetID);

        // Create a new dataset
        log.debug("Workflow launch: Creating dataset {}", datasetName);
        GetDatasetWriteTicketsInputData dataset = CreateDatasetAction.createDataset(session, datasetName, fileCopy, report);

        // Link the part to the dataset (if it fails, it will cleanup the dataset as well)
        log.debug("Workflow launch: Linking  Part {} to newly created dataset {}", target.getUid(), dataset.dataset.getUid());
        LinkFicheArticleAction.linkDatasetToPart(session, target, dataset.dataset);

        // Set status on the dataset
        log.debug("Workflow launch: Adding 'Frozen' status to the dataset {}", dataset.dataset.getUid());
        SetStatusAction.setStatus(session, dataset.dataset, StatusEnum.FROZEN.getIdentifier());

        log.debug("Workflow launch has completed successfully for R15 on ", targetID);

        return null;
    }

    private File copyFile(final String datasetFileNameWithExtension, String originalFileName) throws NotFoundException {
        File copy = new File(OUTPUT_FOLDER + datasetFileNameWithExtension);
        File original = new File(OUTPUT_FOLDER + originalFileName);
        FileHelper.copy(original, copy);
        return copy;
    }

}
