package org.cytoscape.task.internal.table;

import java.util.Arrays;
import java.util.List;

import org.cytoscape.command.StringToModel;
import org.cytoscape.model.CyColumn;
import org.cytoscape.model.CyTable;
import org.cytoscape.service.util.CyServiceRegistrar;
import org.cytoscape.task.internal.utils.TableTunable;
import org.cytoscape.util.json.CyJSONUtil;
import org.cytoscape.work.ContainsTunables;
import org.cytoscape.work.ObservableTask;
import org.cytoscape.work.TaskMonitor;
import org.cytoscape.work.Tunable;
import org.cytoscape.work.json.JSONResult;

public class GetColumnTask extends AbstractTableDataTask implements ObservableTask {
	
	CyColumn returnValue;

	@ContainsTunables
	public TableTunable tableTunable;

	@Tunable(description="Name of column", context="nogui", 
			longDescription=StringToModel.COLUMN_LONG_DESCRIPTION, exampleStringValue = StringToModel.COLUMN_EXAMPLE)
	public String column;

	public GetColumnTask(CyServiceRegistrar serviceRegistrar) {
		super(serviceRegistrar);
		tableTunable = new TableTunable(serviceRegistrar);
	}

	@Override
	public void run(final TaskMonitor tm) {
		CyTable table = tableTunable.getTable();
		if (table == null) {
			tm.showMessage(TaskMonitor.Level.ERROR,  "Unable to find table '"+tableTunable.getTableString()+"'");
			return;
		}

		if (column == null) {
			tm.showMessage(TaskMonitor.Level.ERROR,  "Column name must be specified");
			return;
		}

		returnValue = table.getColumn(column);
		if (returnValue == null) {
			tm.showMessage(TaskMonitor.Level.ERROR,  "Column '"+column+"' doesn't exist in table: "+table.toString());
			return;
		}

		tm.showMessage(TaskMonitor.Level.INFO, "Retrieved column: "+returnValue.toString());
	}
	
	@Override
	public List<Class<?>> getResultClasses() {
		return Arrays.asList(CyColumn.class, String.class, JSONResult.class);
	}

	public Object getResults(Class requestedType) {
		if (returnValue == null) return null;
		if (requestedType.equals(CyColumn.class)) 		return returnValue;
		if (requestedType.equals(String.class)) 		return returnValue.getName();
		if (requestedType.equals(JSONResult.class)) {
			JSONResult res = () -> {	if (returnValue == null) 		return "{}";
			CyJSONUtil cyJSONUtil = serviceRegistrar.getService(CyJSONUtil.class);
			return cyJSONUtil.toJson(returnValue, true, true);
		};
		return res;
		}
		return returnValue;
	}
}
