package com.wpetit.sonar.blame;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The {@link ResourcesManager} class.
 * 
 * @author WPETIT
 * 
 */
public class ResourcesManager {

    /** The LOG. */
    private static final Logger LOG = LoggerFactory.getLogger(ResourcesManager.class);

    /** The sonarBaseUrl. */
    private final String sonarBaseUrl;

    /**
     * Constructor.
     * 
     * @param sonarBaseUrl
     *            the sonar base url
     */
    public ResourcesManager(final String sonarBaseUrl) {
        this.sonarBaseUrl = sonarBaseUrl;
    }

    /**
     * Return the author of the line and component given.
     * 
     * @param componentId
     *            the component
     * @param line
     *            the line
     * @return the author
     */
    public String getLineAuthor(final int componentId, final int line) {
        LOG.info("Retrieving author for line {} of component : {}", line, componentId);
        Client client = ClientBuilder.newClient();
        WebTarget target = client
                .target(sonarBaseUrl)
                .path(ResourcesAPIConstants.ROOT_PATH.getValue())
                .queryParam(ResourcesAPIConstants.RESOURCE.getValue(), componentId)
                .queryParam(ResourcesAPIConstants.METRICS.getValue(),
                        ResourcesAPIConstants.AUTHORS_BY_LINE.getValue());
        JsonArray resources = target.request(MediaType.APPLICATION_JSON).get(JsonArray.class);

        JsonObject resource = resources.getJsonObject(0);

        JsonObject msr = resource.getJsonArray(ResourcesAPIConstants.MSR.getValue()).getJsonObject(
                0);
        Map<Integer, String> authorsByLine = parseAuthorsByLineData(msr
                .getString(ResourcesAPIConstants.DATA.getValue()));
        return authorsByLine.get(line);
    }

    /**
     * Fill a map containing the authors by line from the String api format.
     * 
     * @param authorsByLineData
     *            the initial api response
     * @return the map
     */
    private Map<Integer, String> parseAuthorsByLineData(final String authorsByLineData) {
        Map<Integer, String> authorsByLine = new ConcurrentHashMap<Integer, String>();

        String[] lines = authorsByLineData.split(ResourcesAPIConstants.LINE_SEPARATOR.getValue());
        for (String line : lines) {
            String[] lineData = line.split(ResourcesAPIConstants.LINE_CONTENT_SEPARATOR.getValue());
            authorsByLine.put(Integer.parseInt(lineData[0]), lineData[1]);
        }
        return authorsByLine;
    }

    public int getLastLineCommited(final int componentId) throws ParseException {
        LOG.info("Retrieving last line commited of component : {}", componentId);
        Client client = ClientBuilder.newClient();
        WebTarget target = client
                .target(sonarBaseUrl)
                .path(ResourcesAPIConstants.ROOT_PATH.getValue())
                .queryParam(ResourcesAPIConstants.RESOURCE.getValue(), componentId)
                .queryParam(ResourcesAPIConstants.METRICS.getValue(),
                        ResourcesAPIConstants.LAST_COMMIT_DATETIMES_BY_LINE.getValue());

        JsonArray resources = target.request(MediaType.APPLICATION_JSON).get(JsonArray.class);

        JsonObject resource = resources.getJsonObject(0);

        JsonObject msr = resource.getJsonArray(ResourcesAPIConstants.MSR.getValue()).getJsonObject(
                0);

        return getLastCommitedLineByLineData(msr.getString(ResourcesAPIConstants.DATA.getValue()));
    }

    /**
     * Return the number of the last line commited for the given line data
     * 
     * @param lastCommitDateTimeByLineData
     *            the last_commit_datetimes_by_line data
     * @return the last line commited
     * @throws ParseException
     */
    private int getLastCommitedLineByLineData(final String lastCommitDateTimeByLineData)
            throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss-SSS");

        String[] lines = lastCommitDateTimeByLineData.split(ResourcesAPIConstants.LINE_SEPARATOR
                .getValue());
        int lastCommitedLine = 1;
        Date lastCommitedDate = null;
        for (String line : lines) {
            String[] lineData = line.split(ResourcesAPIConstants.LINE_CONTENT_SEPARATOR.getValue());
            Date lastCommitedDateByLine = simpleDateFormat.parse(lineData[1]);
            if (lastCommitedDate == null || lastCommitedDateByLine.after(lastCommitedDate)) {
                lastCommitedDate = lastCommitedDateByLine;
                lastCommitedLine = Integer.parseInt(lineData[0]);
            }
        }
        return lastCommitedLine;
    }
}

@@ -122,16 +122,42 @@
 .Date;%0D%0A
+import java.util.Locale;%0D%0A
 import j
@@ -3048,24 +3048,287 @@
 ;%0D%0A    %7D%0D%0A%0D%0A
+    /**%0D%0A     * Return the last line commited for the given component.%0D%0A     * %0D%0A     * @param componentId%0D%0A     *            the component id%0D%0A     * @return the line%0D%0A     * @throws ParseException%0D%0A     *             if the line data cannot be parsed%0D%0A     */%0D%0A
     public i
@@ -4390,32 +4390,33 @@
  given line data
+.
 %0D%0A     * %0D%0A     
@@ -4425,39 +4425,20 @@
 @param l
-astCommitDateTimeByL
 ine
+s
 Data%0D%0A  
@@ -4636,49 +4636,17 @@
 ng l
-astCommitDateTimeByL
 ine
+s
 Data)
-%0D%0A           
  thr
@@ -4759,16 +4759,49 @@
 :ss-SSS%22
+,%0D%0A                Locale.ENGLISH
 );%0D%0A%0D%0A  
@@ -4828,31 +4828,12 @@
  = l
-astCommitDateTimeByL
 ine
+s
 Data
@@ -4875,34 +4875,16 @@
 EPARATOR
-%0D%0A                
 .getValu
@@ -5126,30 +5126,24 @@
 e lastCommit
-edDate
 ByLine = sim
@@ -5227,30 +5227,24 @@
 %7C lastCommit
-edDate
 ByLine.after
@@ -5311,22 +5311,16 @@
 stCommit
-edDate
 ByLine;%0D

Clear code