/**
   * Obtains the list of all classes of a project (or module) with their metrics per class.
   *
   * @param resourceKey the project or module to analyse.
   * @return the list of classes of such project or module with their metrics, -1 if metric value
   *     not found.
   */
  public static ArrayList<ClassInfo> getStatisticsPerClass(
      String host, String resourceKey, String[] metricNames) {
    ArrayList<ClassInfo> list = new ArrayList<ClassInfo>();
    Sonar sonar = Sonar.create(host);
    ResourceQuery query = new ResourceQuery(resourceKey);
    query.setMetrics(metricNames);
    query.setScopes("FIL");
    query.setDepth(-1);
    // **************************************************put above and control!
    for (Resource resource : sonar.findAll(query)) {
      ClassInfo classInfo = new ClassInfo();
      classInfo.setClassName(resource.getName());

      for (String metricName : metricNames) {
        Measure measure = resource.getMeasure(metricName);
        //                System.err.println(measure);
        if (measure != null) {
          classInfo.setMetric(metricName, measure.getValue());
        } else {
          System.err.print(
              "Warning[getClassInfos]: "
                  + metricName
                  + " of "
                  + resource.getName()
                  + " is empty. ");
          classInfo.setMetric(metricName, new Double(-1.0));
        }
      }
      list.add(classInfo);
    }
    System.err.println();
    return list;
  }
  public MeasureFinder(String sonarUrl, String login, String password)
      throws SonarMetricsNotFoundException {
    this.sonarUrl = sonarUrl;

    if (isBlank(sonarUrl)) {
      throw new IllegalStateException("sonarUrl can't be null.");
    }
    if (isNotBlank(login) && isNotBlank(password)) {
      sonar = Sonar.create(sonarUrl, login, password);
    } else {
      sonar = Sonar.create(sonarUrl);
    }
  }
  @Test
  public void should_exclude_source_files() {
    assumeTrue(AndroidTestSuite.isAtLeastPlugin1_1());
    SonarRunner analysis =
        SonarRunner.create()
            .setProfile("it-profile")
            .setProjectName("SonarAndroidSample")
            .setProjectKey("SonarAndroidSample")
            .setProjectVersion("1.0")
            .setSourceDirs("app/src/main")
            .setProjectDir(new File("projects/SonarAndroidSample"))
            .setProperty("skipTests", "true")
            .setProperty("sonar.global.exclusions", "**/TestViolations.java")
            .setProperty("sonar.android.lint.report", "lint-results.xml")
            .setProperty("sonar.import_unknown_files", "true");

    orchestrator.executeBuild(analysis);
    Resource project =
        sonar.find(ResourceQuery.createForMetrics("SonarAndroidSample", "violations"));

    int expectedViolations = 0;
    if (AndroidTestSuite.sonarqube_version_is_after_5_1()) {
      // After version 5.1 xml files will be indexed thanks to sonar.import_unknown_files parameter
      // and so issues can be reported on them.
      expectedViolations = 4;
    }
    assertThat(project.getMeasureIntValue("violations")).isEqualTo(expectedViolations);
  }
  @Test
  @Ignore("Deactivated awaiting resolution of http://jira.sonarsource.com/browse/JC-145")
  public void should_run_lint_after_export_and_import_results() throws Exception {
    assumeTrue(AndroidTestSuite.isAtLeastPlugin1_1());
    String response = exportProfile("it-profile");
    File baseDir = new File("projects/SonarAndroidSample/app");
    FileUtils.write(new File(baseDir, "lint.xml"), response, Charsets.UTF_8);
    ProcessBuilder pb = new ProcessBuilder("CMD", "/C", "gradle lint");
    pb.directory(baseDir);
    pb.inheritIO();
    Process gradleProcess = pb.start();
    int exitStatus = gradleProcess.waitFor();
    if (exitStatus != 0) {
      fail("Failed to execute gradle lint.");
    }
    SonarRunner analysis =
        SonarRunner.create()
            .setProfile("it-profile")
            .setProjectName("SonarAndroidSample2")
            .setProjectKey("SonarAndroidSample2")
            .setProjectVersion("1.0")
            .setSourceDirs("src/main")
            .setProjectDir(baseDir)
            .setProperty("sonar.android.lint.report", "lint-report-build.xml")
            .setProperty("sonar.import_unknown_files", "true");
    orchestrator.executeBuild(analysis);
    Resource project =
        sonar.find(ResourceQuery.createForMetrics("SonarAndroidSample2", "violations"));

    assertThat(project.getMeasureIntValue("violations")).isEqualTo(2);
  }
  @Test
  public void favourites_web_service() {
    Sonar adminWsClient = orchestrator.getServer().getAdminWsClient();

    // GET (nothing)
    List<Favourite> favourites = adminWsClient.findAll(new FavouriteQuery());
    assertThat(favourites).isEmpty();

    // POST (create favourites)
    Favourite favourite = adminWsClient.create(new FavouriteCreateQuery("sample"));
    assertThat(favourite).isNotNull();
    assertThat(favourite.getKey()).isEqualTo("sample");
    adminWsClient.create(new FavouriteCreateQuery("sample:src/main/xoo/sample/Sample.xoo"));

    // GET (created favourites)
    favourites = adminWsClient.findAll(new FavouriteQuery());
    assertThat(favourites).hasSize(2);
    List<String> keys =
        newArrayList(
            Iterables.transform(
                favourites,
                new Function<Favourite, String>() {
                  @Override
                  public String apply(Favourite input) {
                    return input.getKey();
                  }
                }));
    assertThat(keys).containsOnly("sample", "sample:src/main/xoo/sample/Sample.xoo");

    // DELETE (a favourite)
    adminWsClient.delete(new FavouriteDeleteQuery("sample"));
    favourites = adminWsClient.findAll(new FavouriteQuery());
    assertThat(favourites).hasSize(1);
    assertThat(favourites.get(0).getKey()).isEqualTo("sample:src/main/xoo/sample/Sample.xoo");
  }
  @VisibleForTesting
  void verifyMeasures(Sonar client) {
    ResourceQuery query = ResourceQuery.create(resourceKey);
    query.setMetrics(
        (String[]) expectedMeasures.keySet().toArray(new String[expectedMeasures.size()]));
    Resource resource = client.find(query);

    if (resource == null) {
      throw new AssertionError("Resource does not exist: " + resourceKey);
    }

    for (Map.Entry<String, String> assertion : expectedMeasures.entrySet()) {
      verifyMeasure(resource, assertion.getKey(), assertion.getValue());
    }
  }
  public Measure findMeasure(String artifactId, String measureKey)
      throws SonarMeasureNotFoundException {
    Preconditions.checkState(
        !Strings.isNullOrEmpty(artifactId), "artifactId is a mandatory parameter");
    Preconditions.checkNotNull(measureKey, "measureKey is a mandatory parameter");

    try {
      ResourceQuery query = ResourceQuery.createForMetrics(artifactId, measureKey);
      Resource resource = sonar.find(query);
      if (resource == null) {
        throw new SonarMeasureNotFoundException(
            "Metric "
                + measureKey
                + " not found for project "
                + artifactId
                + " in Sonar "
                + sonarUrl);
      }
      Measure measure = resource.getMeasure(measureKey);
      if (measure == null) {
        throw new SonarMeasureNotFoundException(
            "Measure ["
                + measureKey
                + "] not found for project "
                + artifactId
                + " in Sonar "
                + sonarUrl);
      }

      return measure;
    } catch (ConnectionException e) {
      throw new SonarMeasureNotFoundException(
          "Metric " + measureKey + " not found for project " + artifactId + " in Sonar " + sonarUrl,
          e);
    }
  }