import java.lang.reflect.InvocationTargetException;

public class BackEndToolImplPluginInline{
	Object httpRequest;
  	Object httpResponse;
  	Object exec;
  	Map arguments;
  
  	Map pluginContext;
  	Object moduleContext; 
  
    Map config;
    Map session;
      
    Object aiProviderInterface;
  	Object aiImplPlugin;
  
    Map toolDefinition = new HashMap();
    Map assistantDefinition = new HashMap();
    Map automations = new HashMap();
  
    public BackEndToolImplPlugin(){

    }
  
    public BackEndToolImplPluginInline(Object httpRequest,Object httpResponse,Map arguments,Object exec){
          this.arguments				= arguments;
          this.httpRequest 				= arguments.get("httpRequest");
          this.httpResponse 			= arguments.get("httpResponse");
          this.exec						= exec;
		  this.pluginContext 			= arguments.get("pluginContext");
      	  this.moduleContext 			= arguments.get("moduleContext"); 
            
          exec.logger().info("BackEndToolImplPluginInline");
    }  
  
    public BackEndToolImplPluginInline setAIContext(Object aiProviderInterface, Object aiImplPlugin){
		this.aiProviderInterface = aiProviderInterface;
  		this.aiImplPlugin = aiImplPlugin;
      	return this;
    }  
  
    public Map draw_shape(Map toolCallArgs,Map tool_call,Map prompt,Map config,Map session,Object aiProviderInterface,Object aiImplPlugin){
      
		Map respMsg = [
            role:"tool",
            tool_call_id:tool_call.id,
            name:tool_call.function.name,
            content:"Shape drawn via crud."
        ];
      
        return respMsg;
    }
  
    public Object init(Map toolImplPluginConfig,Map config,Map session,Object aiProviderInterface,Object aiImplPlugin){
       //toolDefinition = exec.call("<path to tool definitions>/toolDefs{}");
       return this;
    }
  
    public Map preparePrompt(Map prompt,Map config,Map session,Object aiProviderInterface,Object aiImplPlugin){

          if(prompt.apiRequest == null)
          	prompt.put("apiRequest",new HashMap());

          if(prompt.apiRequest.tools == null)
          	prompt.apiRequest.put("tools",new ArrayList());

          //append tools provided by this plugin
          if(prompt.toolDefinition != null && prompt.toolDefinition.defs != null)
          	 prompt.apiRequest.tools.addAll(aiImplPlugin.cloneObject(prompt.toolDefinition.defs));

          List dedupTools = new ArrayList();
          for(Map tool : prompt.apiRequest.tools){
              if(!aiImplPlugin.isInList(dedupTools,t->t.function.name.equals(tool.function.name)))
                  dedupTools.add(tool);
          }
          prompt.apiRequest.put("tools",dedupTools);

          if(prompt.apiRequest.tool_choice == null)
          	prompt.apiRequest.put("tool_choice","auto");

          return prompt;          
    }
  
    public List getTools(Map prompt,Map config,Map session,Object appBuilder,Object aiProviderInterface,Object aiImplPlugin){
      	return getTools(prompt,config,session,aiProviderInterface,aiImplPlugin);
    }
  
    public List getTools(Map prompt,Map config,Map session,Object aiProviderInterface,Object aiImplPlugin){
        return (prompt.toolDefinition != null  && prompt.toolDefinition.defs != null)?aiImplPlugin.cloneObject(prompt.toolDefinition.defs):new ArrayList();
    }
  
    public List getAssistants(Map prompt,Map config,Map session,Object appBuilder,Object aiProviderInterface,Object aiImplPlugin){
      	return getAssistants(prompt,config,session,aiProviderInterface,aiImplPlugin);
    }
  
    public List getAssistants(Map prompt,Map config,Map session,Object aiProviderInterface,Object aiImplPlugin){
        return aiImplPlugin.cloneObject(this.assistantDefinition.defs)
    }
  
    public Map findAutomation(Map prompt,String sourceId,Map config,Map session,Object appBuilder,Object aiProviderInterface,Object aiImplPlugin){
      return findAutomation(prompt,sourceId,config,session,aiProviderInterface,aiImplPlugin);
    }
  
    public Map findAutomation(Map prompt,String sourceId,Map config,Map session,Object aiProviderInterface,Object aiImplPlugin){
        for(Map automation : (new ArrayList<Map>(this.automations.values()))){
           if(automation.id.toString().equals(sourceId))
                  return aiImplPlugin.cloneObject(automation);
        }
        return null;
    }
  
    public boolean isKnownAITool(Map tool_call,Map prompt,Map config,Map session,Object aiProviderInterface,Object aiImplPlugin){
        if(prompt.toolDefinition != null  && prompt.toolDefinition.defs != null){
            for(Map tool: prompt.toolDefinition.defs){
               if(tool.function.name.equals(tool_call.function.name)) 
                  return true;
            }
        }
        return false;
    }
  
    public Object executeToolCool(Map tool_call,Map prompt,Map config,Map session,Object aiProviderInterface,Object aiImplPlugin){
        Map toolCallArgs = new HashMap();
        if(tool_call.function.arguments != null)
         	toolCallArgs = String.class.isInstance(tool_call.function.arguments)?exec.add("solvent_javalang_class","map").eval(tool_call.function.arguments,"json"):tool_call.function.arguments;
      
        String executionEnvironment = prompt.executionEnvironment;
        if(toolCallArgs.executionEnvironment != null && !toolCallArgs.executionEnvironment.equals("any"))
           executionEnvironment = toolCallArgs.executionEnvironment;
          
        if(executionEnvironment != null && executionEnvironment.equals("front-end"))
          	return [sendToClient:true];      
      
      	try
        {
        	return this.getClass().getMethod(tool_call.function.name,Map.class,Map.class,Map.class,Map.class,Map.class,Object.class,Object.class).invoke(this,toolCallArgs,tool_call,prompt,config,session,aiProviderInterface,aiImplPlugin);
        } 
        catch(InvocationTargetException e) {
            throw e.getCause();
        }
    }
}

return new BackEndToolImplPluginInline(arguments.get("httpRequest"),arguments.get("httpResponse"),arguments,exec);
