package agents4;

import jade.content.ContentManager;
import jade.content.lang.Codec;
import jade.content.lang.sl.SLCodec;
import jade.content.onto.Ontology;
import jade.content.onto.OntologyException;
import jade.content.onto.basic.Action;
import jade.core.AID;
import jade.core.Agent;
import jade.core.ContainerID;
import jade.core.Profile;
import jade.core.ProfileImpl;
import jade.core.Runtime;
import jade.core.behaviours.OneShotBehaviour;
import jade.core.behaviours.WakerBehaviour;
import jade.domain.JADEAgentManagement.JADEManagementOntology;
import jade.domain.JADEAgentManagement.KillContainer;
import jade.lang.acl.ACLMessage;


public class Lektorius extends Agent {

    private ContentManager cm;
    private Codec codec;
    private Ontology onto;

    private void print(String data, String behaviourId) {
        if (behaviourId != null)
            System.out.println("A[" + getLocalName() + "|" + behaviourId + "] " + data);
        else
            System.out.println("A[" + getLocalName() + "] " + data);
    }

    /** Sends a container-topology update to the Studentas agent. */
    private void notifyStudentas(String type, String containerName) {
        ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
        msg.addReceiver(new AID("Studentas", AID.ISLOCALNAME));
        msg.setContent(type + ":" + containerName);
        msg.setConversationId("container-update");
        send(msg);
        print("pranešta Studentas: " + type + ":" + containerName, null);
    }

    private void killContainer(String name) {
        KillContainer kc = new KillContainer();
        kc.setContainer(new ContainerID(name, null));

        try {
            Action a = new Action();
            a.setActor(getAMS());
            a.setAction(kc);

            ACLMessage requestMsg = new ACLMessage(ACLMessage.REQUEST);
            requestMsg.setOntology(JADEManagementOntology.NAME);
            requestMsg.setLanguage(codec.getName());
            cm.fillContent(requestMsg, a);
            requestMsg.addReceiver(a.getActor());
            send(requestMsg);
            print("killContainer žinutė išsiųsta AMS: " + name, null);
        } catch (Codec.CodecException | OntologyException e) {
            e.printStackTrace();
        }
    }

    private class TaskBehaviour extends OneShotBehaviour {
        @Override
        public void action() {
            Object[] myArgs = myAgent.getArguments();
            if (myArgs == null || myArgs.length == 0) {
                print("trūksta argumento", "TaskBehaviour");
                myAgent.doDelete();
                return;
            }

            String arg = (String) myArgs[0];
            if (arg.length() < 2) {
                print("argumentas per trumpas: " + arg, "TaskBehaviour");
                myAgent.doDelete();
                return;
            }

            char op = arg.charAt(0);
            String containerName = arg.substring(1);

            if (op == '#') {
                print("kuriamas konteineris: " + containerName, "TaskBehaviour");
                try {
                    ProfileImpl p = new ProfileImpl(false);
                    p.setParameter(Profile.CONTAINER_NAME, containerName);
                    Runtime.instance().createAgentContainer(p);
                    print("konteineris sukurtas: " + containerName, "TaskBehaviour");
                    notifyStudentas("CONTAINER_ADDED", containerName);
                } catch (Exception e) {
                    print("klaida kuriant konteinerį: " + e.getMessage(), "TaskBehaviour");
                }
                myAgent.doDelete();

            } else if (op == '!') {
                print("planuojamas konteinerio sunaikinimas: " + containerName, "TaskBehaviour");
                notifyStudentas("CONTAINER_REMOVED", containerName);

                final String cn = containerName;
                myAgent.addBehaviour(new WakerBehaviour(myAgent, 3000) {
                    @Override
                    protected void onWake() {
                        print("sunaikinamas konteineris: " + cn, "TaskBehaviour");
                        killContainer(cn);
                        myAgent.doDelete();
                    }
                });

            } else {
                print("nežinomas operatorius '" + op + "' argumente: " + arg, "TaskBehaviour");
                myAgent.doDelete();
            }
        }
    }

    @Override
    protected void setup() {
        onto = JADEManagementOntology.getInstance();
        codec = new SLCodec();
        cm = getContentManager();
        cm.registerLanguage(codec);
        cm.registerOntology(onto);

        print("started with arg: " + (getArguments() != null && getArguments().length > 0
            ? getArguments()[0] : "none"), null);
        addBehaviour(new TaskBehaviour());
    }

    @Override
    protected void takeDown() {
        print("terminated", null);
    }
}
