package org.netmelody.cieye.spies.jenkins;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import org.netmelody.cieye.core.domain.Feature;
import org.netmelody.cieye.core.domain.TargetDetail;
import org.netmelody.cieye.core.domain.TargetDigest;
import org.netmelody.cieye.core.domain.TargetDigestGroup;
import org.netmelody.cieye.core.domain.TargetId;
import org.netmelody.cieye.core.logging.LogKeeper;
import org.netmelody.cieye.core.logging.Logbook;
import org.netmelody.cieye.core.observation.CiSpy;
import org.netmelody.cieye.core.observation.Contact;
import org.netmelody.cieye.core.observation.KnownOffendersDirectory;
import org.netmelody.cieye.spies.jenkins.jsondomain.Job;
import org.netmelody.cieye.spies.jenkins.jsondomain.View;

import com.google.common.base.Predicate;

import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;

public final class JenkinsSpy implements CiSpy {
    
    private static final Logbook LOG = LogKeeper.logbookFor(JenkinsSpy.class);
    
    private final JenkinsCommunicator communicator;
    private final JobLaboratory laboratory;
    
    private final Map<TargetId, Job> recognisedJobs = newHashMap();
    
    public JenkinsSpy(String endpoint, KnownOffendersDirectory detective, Contact contact) {
        this.communicator = new JenkinsCommunicator(endpoint, contact);
        this.laboratory = new JobLaboratory(communicator, detective);
    }

    @Override
    public TargetDigestGroup targetsConstituting(Feature feature) {
        final Collection<Job> jobs = jobsFor(feature);
        final List<TargetDigest> digests = newArrayList();
        
        for (Job job : jobs) {
            final TargetDigest targetDigest = new TargetDigest(job.url, job.url, job.name, job.status());
            digests.add(targetDigest);
            recognisedJobs.put(targetDigest.id(), job);
        }
        
        return new TargetDigestGroup(digests);
    }

    @Override
    public TargetDetail statusOf(final TargetId target) {
        Job job = recognisedJobs.get(target);
        if (null == job) {
            return null;
        }
        return laboratory.analyseJob(job);
    }

    @Override
    public boolean takeNoteOf(TargetId target, String note) {
        if (!recognisedJobs.containsKey(target)) {
            return false;
        }
        
        final Job job = this.recognisedJobs.get(target);
        final String buildUrl = this.laboratory.lastBadBuildUrlFor(job);
        
        if (buildUrl.isEmpty()) {
            return true;
        }
        
        communicator.doJenkinsPost(buildUrl +
                                   "submitDescription?" +
                                   URLEncodedUtils.format(newArrayList(new BasicNameValuePair("description", note)), "UTF-8"));
        return true;
    }
    
    private Collection<Job> jobsFor(final Feature feature) {
        if (!communicator.canSpeakFor(feature)) {
            return newArrayList();
        }
        
        final View viewDigest = find(communicator.views(), withName(feature.name()), null);
        if (null == viewDigest) {
            LOG.error("No view named <" + feature.name() + "> found");
            return newArrayList();
        }
        
        return communicator.jobsFor(viewDigest);
    }

    private Predicate<View> withName(final String featureName) {
        return new Predicate<View>() {
            @Override public boolean apply(View viewDigest) {
                return viewDigest.name.trim().equals(featureName.trim());
            }
        };
    }
}

@@ -3186,32 +3186,111 @@
      %7D%0A        %0A
+        final String name = feature.name().isEmpty() ? %22All%22 : feature.name();%0A
         final Vi
@@ -3341,30 +3341,20 @@
 ithName(
-feature.
 name
-()
 ), null)
@@ -3431,30 +3431,20 @@
 ed %3C%22 + 
-feature.
 name
-()
  + %22%3E fo

support for "All" view on jenkins -- refs #6