package lemming.context.inbound;

import lemming.context.Context;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.IModel;

import javax.ws.rs.core.MultivaluedMap;
import java.util.ArrayList;
import java.util.List;

/**
 * A form for the verification of inbound contexts.
 */
class InboundContextVerificationForm extends Form<InboundContextPackage> {

    RepeatingView repeatingView;

    /**
     * Creates a context verify form.
     *
     * @param model model of a group of inbound contexts
     */
    public InboundContextVerificationForm(IModel<InboundContextPackage> model) {
        super("InboundContextVerificationForm", model);
        add(new SubmitButton(this));

        repeatingView = new RepeatingView("repeater");
        add(repeatingView);
    }

    @Override
    protected void onInitialize() {
        super.onInitialize();
        InboundContextPackage contextPackage = getModelObject();

        matchContextsByHash();
        List<String> unmatchedLocations = findUnmatchedLocations(contextPackage);

        for (String location : unmatchedLocations) {
            List<InboundContext> unmatchedContexts = new InboundContextPackageDao()
                    .findUnmatchedContextsByLocation(contextPackage, location);
            List<Context> complements = new InboundContextDao().findPossibleComplements(unmatchedContexts);

            if (complements != null) {
                List<Triple> matchingTriples = computeMatchingTriples(unmatchedContexts, complements);
                List<InboundContext> contextsWithoutComplement = getContextsWithoutComplement(unmatchedContexts,
                        matchingTriples);
                List<Context> complementsWithoutContext = getComplementsWithoutContext(complements, matchingTriples);
                ContextTreeProvider provider = new ContextTreeProvider(matchingTriples, complementsWithoutContext);

                repeatingView.add(new ContextTreePanel(repeatingView.newChildId(), location, provider,
                        contextsWithoutComplement));
            }
        }


//            MultivaluedMap<Integer, InboundContext> groupedContexts = new InboundContextPackageDao()
//                    .groupUnmatchedContexts(contextPackage, location);
//
//            for (Integer key : groupedContexts.keySet()) {
//                List<InboundContext> inboundContexts = groupedContexts.get(key);
//                List<Context> complements = new InboundContextDao().findComplements(inboundContexts);
//
//                // TODO: what now?
//                if (complements != null) {
//                    List<Triple> matchingTriples = computeMatchingTriples(inboundContexts, complements);
//                    List<InboundContext> contextsWithoutComplement = getContextsWithoutComplement(inboundContexts,
//                            matchingTriples);
//                    List<Context> complementsWithoutContext = getComplementsWithoutContext(complements,
//                            matchingTriples);
//                    ContextTreeProvider provider = new ContextTreeProvider(matchingTriples,
//                            complementsWithoutContext);
//
//                    repeatingView.add(new ContextTreePanel(repeatingView.newChildId(), location, provider,
//                            contextsWithoutComplement));
//                }
//            }

        // TODO: show something else
        if (repeatingView.size() == 0) {
            repeatingView.setVisible(false);
        }
    }

    /**
     * Match contexts by hash.
     */
    private void matchContextsByHash() {
        InboundContextPackage contextPackage = getModelObject();
        new InboundContextPackageDao().matchContextsByHash(contextPackage);
    }

    /**
     * Finds and sets locations with unmatched contexts.
     *
     * @param contextPackage package of inbound contexts
     */
    private List<String> findUnmatchedLocations(InboundContextPackage contextPackage) {
        return new InboundContextPackageDao().findUnmatchedContextLocations(contextPackage);
    }

    /**
     * Computes matching triples for a list of contexts.
     *
     * @param contexts a list of inbound contexts
     * @param complements a list of context complements
     * @return A list of matching triples.
     */
    private List<Triple> computeMatchingTriples(List<InboundContext> contexts, List<Context> complements) {
        if (complements != null) {
            MultivaluedMap<Integer, Triple> distanceMap = MatchHelper.getTriples(complements, contexts);
            return MatchHelper.computeMatchingTriples(distanceMap);
        }

        return new ArrayList<>();
    }

    private List<InboundContext> getContextsWithoutComplement(List<InboundContext> inboundContexts,
                                                              List<Triple> matchingTriples) {
        List<InboundContext> unmatchedInboundContexts = new ArrayList<>(inboundContexts);

        for (Triple triple : matchingTriples) {
            unmatchedInboundContexts.remove(triple.getInboundContext());
        }

        return unmatchedInboundContexts;
    }

    private List<Context> getComplementsWithoutContext(List<Context> complements,
                                                       List<Triple> matchingTriples) {
        List<Context> unmatchedComplements = new ArrayList<>(complements);

        for (Triple triple : matchingTriples) {
            unmatchedComplements.remove(triple.getContext());
        }

        return unmatchedComplements;
    }

    private class SubmitButton extends AjaxButton {

        SubmitButton(Form<InboundContextPackage> form) {
            super("submitButton", form);
        }

        /**
         * Called on form submit.
         *
         * @param target target that produces an Ajax response
         * @param form the parent form
         */
        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
            super.onSubmit(target, form);
        }
    }
}

@@ -1098,24 +1098,110 @@
 lObject();%0A%0A
+        if (!new InboundContextPackageDao().hasMatchedContexts(contextPackage)) %7B%0A    
         matc
@@ -1215,24 +1215,35 @@
 tsByHash();%0A
+        %7D%0A%0A
         List
@@ -1548,33 +1548,41 @@
   List%3CContext%3E 
-c
+possibleC
 omplements = new
@@ -1650,52 +1650,8 @@
 s);%0A
-%0A            if (complements != null) %7B%0A    
     
@@ -1723,33 +1723,41 @@
 atchedContexts, 
-c
+possibleC
 omplements);%0A   
@@ -1749,28 +1749,24 @@
 mplements);%0A
-    
             
@@ -1874,36 +1874,32 @@
                 
-    
 matchingTriples)
@@ -1904,36 +1904,32 @@
 s);%0A            
-    
 List%3CContext%3E co
@@ -1930,1343 +1930,94 @@
 xt%3E 
-complementsWithoutContext = getComplementsWithoutContext(complements, matchingTriples);%0A                ContextTreeProvider provider = new ContextTreeProvider(matchingTriples, complementsWithoutContext);%0A%0A                repeatingView.add(new ContextTreePanel(repeatingView.newChildId(), location, provider,%0A                        contextsWithoutComplement));%0A            %7D%0A        %7D%0A%0A%0A//            MultivaluedMap%3CInteger, InboundContext%3E groupedContexts = new InboundContextPackageDao()%0A//                    .groupUnmatchedContexts(contextPackage, location);%0A//%0A//            for (Integer key : groupedContexts.keySet()) %7B%0A//                List%3CInboundContext%3E inboundContexts = groupedContexts.get(key);%0A//                List%3CContext%3E complements = new InboundContextDao().findComplements(inboundContexts);%0A//%0A//                // TODO: what now?%0A//                if (complements != null) %7B%0A//                    List%3CTriple%3E matchingTriples = computeMatchingTriples(inboundContexts, complements);%0A//                    List%3CInboundContext%3E contextsWithoutComplement = getContextsWithoutComplement(inboundContexts,%0A//                            matchingTriples);%0A//                    List%3CContext%3E complementsWithoutContext = getComplementsWithoutContext(complements,%0A//                            matchingTriples);%0A//        
+unmatchedComplements = getUnmatchedComplements(possibleComplements, matchingTriples);%0A
     
@@ -2099,72 +2099,33 @@
 les,
-%0A//                            complementsWithoutContext);%0A//%0A//
+ unmatchedComplements);%0A%0A
     
@@ -2128,32 +2128,24 @@
             
-        
 repeatingVie
@@ -2219,26 +2219,16 @@
 ovider,%0A
-//        
         
@@ -2272,34 +2272,8 @@
 ));%0A
-//                %7D%0A//    
     
@@ -4071,16 +4071,25 @@
 ext%3E get
+Unmatched
 Compleme
@@ -4095,22 +4095,8 @@
 ents
-WithoutContext
 (Lis
@@ -4115,29 +4115,24 @@
 omplements,%0A
-     
             

Simplify verification of contexts.