/*
 * 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.sysds.runtime.instructions;

import org.apache.sysds.lops.LopProperties.ExecType;
import org.apache.sysds.runtime.DMLRuntimeException;
import org.apache.sysds.runtime.instructions.cp.CPInstruction.CPType;
import org.apache.sysds.runtime.instructions.fed.FEDInstruction;
import org.apache.sysds.runtime.instructions.gpu.GPUInstruction.GPUINSTRUCTION_TYPE;
import org.apache.sysds.runtime.instructions.spark.SPInstruction.SPType;


public class InstructionParser 
{
	public static Instruction parseSingleInstruction ( String str ) {
		if ( str == null || str.isEmpty() )
			return null;
		
		ExecType et = InstructionUtils.getExecType(str);
		switch( et ) {
			case CP:
			case CP_FILE: {
				CPType cptype = InstructionUtils.getCPType(str);
				if( cptype == null )
					throw new DMLRuntimeException("Unknown CP instruction: " + str);
				return CPInstructionParser.parseSingleInstruction (cptype, str);
			}
			case SPARK: {
				SPType sptype = InstructionUtils.getSPType(str);
				if( sptype == null )
					throw new DMLRuntimeException("Unknown SPARK instruction: " + str);
				return SPInstructionParser.parseSingleInstruction (sptype, str);
			}
			case GPU: {
				GPUINSTRUCTION_TYPE gputype = InstructionUtils.getGPUType(str);
				if( gputype == null )
					throw new DMLRuntimeException("Unknown GPU instruction: " + str);
				return GPUInstructionParser.parseSingleInstruction (gputype, str);
			}
			case FED: {
				FEDInstruction.FEDType fedtype = InstructionUtils.getFEDType(str);
				if( fedtype == null )
					throw new DMLRuntimeException("Unknown FEDERATED instruction: " + str);
				return FEDInstructionParser.parseSingleInstruction (fedtype, str);
			}
			default:
				throw new DMLRuntimeException("Unknown execution type in instruction: " + str);
		}
	}
	
	public static Instruction[] parseMixedInstructions ( String str ) {
		if ( str == null || str.isEmpty() )
			return null;
		String[] strlist = str.split(Instruction.INSTRUCTION_DELIM);
		Instruction[] inst = new Instruction[strlist.length];
		for ( int i=0; i < inst.length; i++ )
			inst[i] = parseSingleInstruction ( strlist[i] );
		return inst;
	}
}
