/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.apache.taverna.scufl2.cwl;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;

import java.lang.NullPointerException;

import org.yaml.snakeyaml.Yaml;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;


import org.apache.taverna.scufl2.api.core.Workflow;
import org.apache.taverna.scufl2.api.core.Processor;
import org.apache.taverna.scufl2.api.core.DataLink;

import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
import org.apache.taverna.scufl2.api.port.InputProcessorPort;
import org.apache.taverna.scufl2.api.port.OutputProcessorPort;
import org.apache.taverna.scufl2.api.port.SenderPort;
import org.apache.taverna.scufl2.api.port.ReceiverPort;

import org.apache.taverna.scufl2.api.container.WorkflowBundle;

import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
import org.apache.taverna.scufl2.api.io.WriterException;

public class WorkflowParser {

    private static final String FILE_NAME = "/hello_world.cwl";
    private CWLParser cwlParser;
    private Converter converter;

    private Map<String, InputWorkflowPort> workflowInputs;
    private Map<String, OutputWorkflowPort> workflowOutputs;
    private Map<String, Processor> workflowProcessors;
    private Map<String, InputProcessorPort> processorInputs;
    private Map<String, OutputProcessorPort> processorOutputs;
    private Set<DataLink> dataLinks;

    public WorkflowParser() {
        Yaml reader = new Yaml();
        ObjectMapper mapper = new ObjectMapper();
        JsonNode cwlFile = mapper.valueToTree(reader.load(WorkflowParser.class.getResourceAsStream(FILE_NAME)));
        this.cwlParser = new CWLParser(cwlFile);
        this.converter = new Converter();
        workflowInputs = new HashMap<>();
        workflowOutputs = new HashMap<>();
        workflowProcessors = new HashMap<>();
        processorInputs = new HashMap<>();
        processorOutputs = new HashMap<>();
        dataLinks = new HashSet<DataLink>();
    }

    public WorkflowParser(JsonNode cwlFile) {
        this.cwlParser = new CWLParser(cwlFile);
        this.converter = new Converter();
        workflowInputs = new HashMap<>();
        workflowOutputs = new HashMap<>();
        workflowProcessors = new HashMap<>();
        processorInputs = new HashMap<>();
        processorOutputs = new HashMap<>();
        dataLinks = new HashSet<DataLink>();
    }

    public Workflow buildWorkflow() {
        parseInputs();
        parseOutputs();
        Set<Step> cwlSteps = cwlParser.parseSteps();
        parseProcessors(cwlSteps);
        parseDataLinks(cwlSteps);

        Workflow workflow = new Workflow();
        Set<InputWorkflowPort> inputs = new HashSet<>(workflowInputs.values());
        Set<OutputWorkflowPort> outputs = new HashSet<>(workflowOutputs.values());
        Set<Processor> processors = new HashSet<>(workflowProcessors.values());

        workflow.setInputPorts(inputs);
        workflow.setOutputPorts(outputs);
        workflow.setProcessors(processors);
        workflow.setDataLinks(dataLinks);

//        writeWorkflowToFile(workflow);

        return workflow;
    }

    public void writeWorkflowToFile(Workflow workflow) {
        try {
            WorkflowBundleIO io = new WorkflowBundleIO();
            File scufl2File = new File("workflow.wfbundle");
            WorkflowBundle bundle = io.createBundle();
            Set<Workflow> workflowSet = new HashSet<>();
            workflowSet.add(workflow);
            bundle.setWorkflows(workflowSet);
            bundle.setMainWorkflow(workflow);
            io.writeBundle(bundle, scufl2File, "application/vnd.taverna.scufl2.workflow-bundle");
        } catch(WriterException e) {
            System.out.println("Exception writing the workflow bundle");
        } catch(IOException e) {
            System.out.println("IOException");
        }
    }

    public void parseInputs() {
        Set<PortDetail> cwlInputs = cwlParser.parseInputs();
        if(cwlInputs != null) {
            for (PortDetail port : cwlInputs) {
                String portId = port.getId();
                InputWorkflowPort workflowPort = converter.convertInputWorkflowPort(port);
                workflowInputs.put(portId, workflowPort);
            }
        }
    }

    public void parseOutputs() {
        Set<PortDetail> cwlOutputs = cwlParser.parseOutputs();
        for(PortDetail port: cwlOutputs) {
            String portId = port.getId();
            OutputWorkflowPort workflowPort = converter.convertOutputWorkflowPort(port);
            workflowOutputs.put(portId, workflowPort);
        }
    }

    public void parseProcessors(Set<Step> cwlSteps) {
        for(Step step: cwlSteps) {
            Processor processor = converter.convertStepToProcessor(step);
            workflowProcessors.put(step.getId(), processor);

            for(StepInput stepInput: step.getInputs()) {
                InputProcessorPort processorPort = new InputProcessorPort(processor, stepInput.getId());
                processorInputs.put(stepInput.getId(), processorPort);
            }
            for(StepOutput stepOutput: step.getOutputs()) {
                OutputProcessorPort processorPort = new OutputProcessorPort(processor, stepOutput.getId());
                processorOutputs.put(stepOutput.getId(), processorPort);
            }
        }
    }

    public void parseDataLinks(Set<Step> cwlSteps) {
        for(Step step: cwlSteps) {
            for(StepInput stepInput: step.getInputs()) {
                String[] sourcePath = stepInput.getSource().split("/");
                String source = sourcePath[sourcePath.length-1];
                source = source.replace("#", "");

                DataLink dataLink = new DataLink();
                SenderPort sender = workflowInputs.get(source);
                if(sender == null) {
                    sender = processorOutputs.get(source);
                }
                if(sender == null) {
                    throw new NullPointerException("Cannot find sender port with name: " + source);
                }
                String receiverId = stepInput.getId();
                ReceiverPort receiver = workflowOutputs.get(receiverId);
                if(receiver == null) {
                    receiver = processorInputs.get(receiverId);
                }
                if(receiver == null) {
                    throw new NullPointerException("Cannot find receiver port with name: " + receiverId);
                }
                dataLink.setSendsTo(receiver);
                dataLink.setReceivesFrom(sender);
                dataLinks.add(dataLink);
            }
        }
    }

    public Map<String, InputWorkflowPort> getWorkflowInputs() {
        return workflowInputs;
    }

    public void setWorkflowInputs(Map<String, InputWorkflowPort> workflowInputs) {
        this.workflowInputs = workflowInputs;
    }

    public Map<String, OutputWorkflowPort> getWorkflowOutputs() {
        return workflowOutputs;
    }

    public void setWorkflowOutputs(Map<String, OutputWorkflowPort> workflowOutputs) {
        this.workflowOutputs = workflowOutputs;
    }

    public Map<String, Processor> getWorkflowProcessors() {
        return workflowProcessors;
    }

    public void setWorkflowProcessors(Map<String, Processor> workflowProcessors) {
        this.workflowProcessors = workflowProcessors;
    }

    public Map<String, InputProcessorPort> getProcessorInputs() {
        return processorInputs;
    }

    public void setProcessorInputs(Map<String, InputProcessorPort> processorInputs) {
        this.processorInputs = processorInputs;
    }

    public Map<String, OutputProcessorPort> getProcessorOutputs() {
        return processorOutputs;
    }

    public void setProcessorOutputs(Map<String, OutputProcessorPort> processorOutputs) {
        this.processorOutputs = processorOutputs;
    }

    public Set<DataLink> getDataLinks() {
        return dataLinks;
    }

    public void setDataLinks(Set<DataLink> dataLinks) {
        this.dataLinks = dataLinks;
    }
}