/*
 * Copyright 2012 JBoss by Red Hat.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jbpm.kie.services.impl.example;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.jbpm.shared.services.api.FileService;
import org.kie.api.runtime.process.WorkItem;
import org.kie.api.runtime.process.WorkItemHandler;
import org.kie.api.runtime.process.WorkItemManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 */
public class MoveFileWorkItemHandler implements WorkItemHandler {
    
    private static final Logger logger = LoggerFactory.getLogger(MoveFileWorkItemHandler.class);

    public final static String WIP_INPUT_RELEASE = "in_release_path";
    public final static String WIP_INPUT_SOURCE = "in_source_dir";
    public final static String WIP_INPUT_TARGET = "in_target_dir";
    public final static String WIP_INPUT_FILES = "in_files";
    public final static String WIP_INPUT_KEEP_ORIGINAL_FILES = "in_keep_original_files";
    public final static String WIP_OUTPUT_ERRORS = "out_errors";
    
    public final static boolean KEEP_ORIGINAL_FILES_DEFAULT_VALUE = false;
    
    @Inject
    private FileService fs;
    
    public MoveFileWorkItemHandler() {
        
    }
    public MoveFileWorkItemHandler(FileService fs) {
        this.fs = fs;
    }

    @Override
    public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
        // Debug only
        logger.debug("############ Work Item Parameters");
        for (String k : workItem.getParameters().keySet()) {
            logger.debug("Key = {} - value {}", k, workItem.getParameter(k));
        }
        logger.debug("#################################");
        
        Map<String, String> errors = new LinkedHashMap<String, String>();

        //Read release path
        String release = (String) workItem.getParameter(WIP_INPUT_RELEASE);

        //Read source dir
        String source = (String) workItem.getParameter(WIP_INPUT_SOURCE);

        //Read file list
        String filesNames = (String) workItem.getParameter(WIP_INPUT_FILES);

        //Read destination dir
        String destination = (String) workItem.getParameter(WIP_INPUT_TARGET);

        //keep original files
        boolean keepOriginalFiles = workItem.getParameter("WIP_INPUT_KEEP_ORIGINAL_FILES") != null ? Boolean.parseBoolean(workItem.getParameter("WIP_INPUT_KEEP_ORIGINAL_FILES").toString()):KEEP_ORIGINAL_FILES_DEFAULT_VALUE;

        //check mandatory parameters
        if (filesNames == null || filesNames.isEmpty()) {
            throw new IllegalArgumentException("'" + WIP_INPUT_FILES + "' parameter is mandatory!");
        }

        if (destination == null || destination.isEmpty()) {
            throw new IllegalArgumentException("'" + WIP_INPUT_TARGET + "' parameter is mandatory!");
        }

        if (source == null || source.isEmpty()) {
            throw new IllegalArgumentException("'" + WIP_INPUT_SOURCE + "' parameter is mandatory!");
        }

        if (release == null || release.isEmpty()) {
            throw new IllegalArgumentException("'" + WIP_INPUT_RELEASE + "' parameter is mandatory!");
        }

        //separate file names
        List<String> files = Arrays.asList(filesNames.trim().split(","));


        //create full paths
        source = release + "/" + source;
        destination = release + "/" + destination;


        //Destination must exist
        if (fs.exists(fs.getPath(destination))) {
            //Move each file to destination. If the file doesn't exist put it 
            //in the errors map
            for (String file : files) {
                String fqn = source + "/" + file.trim();

                try {
                    if (!fs.exists(fs.getPath(fqn))) {
                        errors.put(fqn, "Doesn't exist");
                        continue;
                    }
                    if (keepOriginalFiles){
                        fs.copy(fs.getPath(fqn), fs.getPath(destination + "/" + file.trim()));
                    }else{
                        fs.move(fs.getPath(fqn), fs.getPath(destination + "/" + file.trim()));
                    }
                        
                } catch (Exception e) {
                    errors.put(fqn, e.getMessage());
                }
            }
        } else {
            errors.put("destination", "Doesn't exist");
        }


        //convert errors to String
        StringBuilder errorsString = new StringBuilder("");
        for (Map.Entry<String, String> entry : errors.entrySet()) {
            if (errorsString.length() != 0) {
                errorsString.append(",");
            }
            errorsString.append("[").append(entry.getKey()).append("] -> ").append(entry.getValue());
        }

        //Complete work item
        Map<String, Object> results = new HashMap<String, Object>();
        results.put(WIP_OUTPUT_ERRORS, errorsString.toString());
        logger.debug("############ Work Item Outputs");
        logger.debug(" ERRORS: {}", errorsString.toString());
        logger.debug("#################################");
        manager.completeWorkItem(workItem.getId(), results);

    }

    @Override
    public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
    }
}
