/*
 * 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.util.Set;
import java.util.Map;
import java.util.HashMap;

import com.fasterxml.jackson.databind.JsonNode;

import org.apache.taverna.scufl2.api.port.InputProcessorPort;
import org.apache.taverna.scufl2.api.port.OutputProcessorPort;

public class CommandLineTool implements Process {

    private final static String BASE_COMMAND = "baseCommand";
    private final static String ID = "id";
    private final static String INPUT_BINDINDGS = "inputBinding";

    private CWLParser cwlParser;

    private JsonNode node;

    private String baseCommand = null;
    private Map<String, InputProcessorPort> processorInputs;
    private Map<String, OutputProcessorPort> processorOutputs;

    public CommandLineTool(JsonNode node) {
        this.node = node;
        this.cwlParser = new CWLParser(node);
        this.processorInputs = new HashMap<>();
        this.processorOutputs = new HashMap<>();
        this.parse();
        this.receiverPorts = new HashSet(processorInputs.values());
        this.senderPorts = new HashSet(processorOutputs.values());
    }

    public void parse() {
        baseCommand = node.get(BASE_COMMAND).asText();
        parseInputs();
        parseOutputs();
    }

    public void parseInputs() {
        Set<PortDetail> cwlInputs = cwlParser.parseInputs();
        for(PortDetail detail: cwlInputs) {
            String portId = detail.getId();
            InputProcessorPort port = new InputProcessorPort();
            port.setName(portId);
            processorInputs.put(portId, port);
        }
    }

    public void parseOutputs() {
        Set<PortDetail> cwlOutputs = cwlParser.parseOutputs();
        for(PortDetail detail: cwlOutputs) {
            String portId = detail.getId();
            OutputProcessorPort port = new OutputProcessorPort();
            port.setName(portId);
            processorOutputs.put(portId, port);
        }
    }
}