package agents;

import jade.core.Agent;
import jade.core.behaviours.CyclicBehaviour;
import jade.domain.DFService;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

public class Provider extends Agent {

    private boolean hasService1;
    private boolean hasService2;
    private boolean hasService3;

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

    private class ListenBehaviour extends CyclicBehaviour {
        @Override
        public void action() {
            // Only consume messages not matched by ForbiddenSrvcBehaviour
            MessageTemplate mt = MessageTemplate.not(
                MessageTemplate.and(
                    MessageTemplate.MatchPerformative(ACLMessage.INFORM),
                    MessageTemplate.MatchContent("ForbiddenSrvc")
                )
            );
            ACLMessage msg = myAgent.receive(mt);
            if (msg != null) {
                print("received: " + msg.getContent(), "ListenBehaviour");
            } else {
                block();
            }
        }
    }

    private class ForbiddenSrvcBehaviour extends CyclicBehaviour {
        @Override
        public void action() {
            MessageTemplate mt = MessageTemplate.and(
                MessageTemplate.MatchPerformative(ACLMessage.INFORM),
                MessageTemplate.MatchContent("ForbiddenSrvc")
            );
            ACLMessage msg = myAgent.receive(mt);
            if (msg != null) {
                if (hasService1) {
                    print("ForbiddenSrvc received – deleting self", "ForbiddenSrvcBehaviour");
                    myAgent.doDelete();
                } else {
                    print("ForbiddenSrvc received – ignored (no Service1)", "ForbiddenSrvcBehaviour");
                }
            } else {
                block();
            }
        }
    }

    @Override
    protected void setup() {
        Object[] args = getArguments();
        hasService1 = args != null && args.length > 0 && "1".equals(args[0]);
        hasService2 = args != null && args.length > 1 && "1".equals(args[1]);
        hasService3 = args != null && args.length > 2 && "1".equals(args[2]);

        print("starting – s1=" + (hasService1 ? 1 : 0)
            + " s2=" + (hasService2 ? 1 : 0)
            + " s3=" + (hasService3 ? 1 : 0), null);

        DFAgentDescription dfd = new DFAgentDescription();
        dfd.setName(getAID());

        if (hasService1) {
            ServiceDescription sd = new ServiceDescription();
            sd.setType("Service1");
            sd.setName("Service1");
            dfd.addServices(sd);
        }
        if (hasService2) {
            ServiceDescription sd = new ServiceDescription();
            sd.setType("Service2");
            sd.setName("Service2");
            dfd.addServices(sd);
        }
        if (hasService3) {
            ServiceDescription sd = new ServiceDescription();
            sd.setType("Service3");
            sd.setName("Service3");
            dfd.addServices(sd);
        }

        try {
            DFService.register(this, dfd);
            print("registered with DF", null);
        } catch (FIPAException e) {
            print("DF register error: " + e.getMessage(), null);
        }

        addBehaviour(new ListenBehaviour());
        addBehaviour(new ForbiddenSrvcBehaviour());
    }

    @Override
    protected void takeDown() {
        try {
            DFService.deregister(this);
            print("deregistered from DF", null);
        } catch (FIPAException e) {
        }
        print("terminated", null);
    }
}
