// Path: src/main/java/org/sonar/plugins/stash/issue/StashDiffReport.java
// public class StashDiffReport {
// 
//   public static final int VICINITY_RANGE_NONE = 0;
// 
//   private List<StashDiff> diffs;
// 
//   public StashDiffReport() {
//     this.diffs = new ArrayList<>();
//   }
// 
//   public List<StashDiff> getDiffs() {
//     return Collections.unmodifiableList(diffs);
//   }
// 
//   public void add(StashDiff diff) {
//     diffs.add(diff);
//   }
// 
//   public void add(StashDiffReport report) {
//     diffs.addAll(report.getDiffs());
//   }
// 
//   private static boolean inVicinityOfChangedDiff(StashDiff diff, long destination, int range) {
//     if (range <= 0) {
//       return false;
//     }
//     long lower = Math.min(diff.getSource(), diff.getDestination());
//     long upper = Math.max(diff.getSource(), diff.getDestination());
//     return Range.closed(lower - range, upper + range).contains(destination);
//   }
// 
//   private static boolean isChangedDiff(StashDiff diff, long destination) {
//     return diff.getDestination() == destination;
//   }
// 
//   private static boolean lineIsChangedDiff(StashDiff diff) {
//     return !diff.getType().equals(IssueType.CONTEXT);
//   }
// 
//   public IssueType getType(String path, long destination, int vicinityRange) {
//     boolean isInContextDiff = false;
//     for (StashDiff diff : diffs) {
//       if (Objects.equals(diff.getPath(), path)) {
//         // Line 0 never belongs to Stash Diff view.
//         // It is a global comment with a type set to CONTEXT.
//         if (destination == 0) {
//           return IssueType.CONTEXT;
//         } else if (!lineIsChangedDiff(diff)) {
//           // We only care about changed diff
//           continue;
//         } else if (isChangedDiff(diff, destination)) {
//           return diff.getType();
//         } else if (inVicinityOfChangedDiff(diff, destination, vicinityRange)) {
//           isInContextDiff = true;
//         }
//       }
//     }
//     return isInContextDiff ? IssueType.CONTEXT : null;
//   }
// 
//   /**
//    * Depends on the type of the diff.
//    * If type == "CONTEXT", return the source line of the diff.
//    * If type == "ADDED", return the destination line of the diff.
//    */
//   public long getLine(String path, long destination) {
//     for (StashDiff diff : diffs) {
//       if (Objects.equals(diff.getPath(), path) && (diff.getDestination() == destination)) {
// 
//         if (diff.getType() == IssueType.CONTEXT) {
//           return diff.getSource();
//         } else {
//           return diff.getDestination();
//         }
//       }
//     }
//     return 0;
//   }
// 
//   public StashDiff getDiffByComment(long commentId) {
//     for (StashDiff diff : diffs) {
//       if (diff.containsComment(commentId)) {
//         return diff;
//       }
//     }
//     return null;
//   }
// 
//   /**
//    * Get all comments from the Stash differential report.
//    */
//   public List<StashComment> getComments() {
//     List<StashComment> result = new ArrayList<>();
// 
//     for (StashDiff diff : this.diffs) {
//       List<StashComment> comments = diff.getComments();
// 
//       for (StashComment comment : comments) {
//         if (!result.contains(comment)) {
//           result.add(comment);
//         }
//       }
//     }
//     return result;
//   }
// }


import com.google.common.collect.Lists;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.sonar.api.Plugin;
import org.sonar.api.Properties;
import org.sonar.api.Property;
import org.sonar.api.PropertyType;
import org.sonar.api.batch.rule.Severity;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.resources.Qualifiers;
import java.util.List;
import org.sonar.plugins.stash.issue.StashDiffReport;

package org.sonar.plugins.stash;



@Properties({
                @Property(key = StashPlugin.STASH_NOTIFICATION,
                          name = "Stash Notification",
                          defaultValue = "false",
                          description = "Analysis result will be issued in Stash pull request",
                          global = false),
                @Property(key = StashPlugin.STASH_PROJECT,
                          name = "Stash Project",
                          description = "Stash project of current pull-request",
                          global = false),
                @Property(key = StashPlugin.STASH_REPOSITORY,
                          name = "Stash Repository",
                          description = "Stash project of current pull-request",
                          global = false),
                @Property(key = StashPlugin.STASH_PULL_REQUEST_ID,
                          name = "Stash Pull-request Id",
                          description = "Stash pull-request Id",
                          global = false)})

public class StashPlugin implements Plugin {

  private static final String DEFAULT_STASH_TIMEOUT_VALUE = "10000";
  private static final String DEFAULT_STASH_THRESHOLD_VALUE = "100";
  private static final boolean DEFAULT_STASH_ANALYSIS_OVERVIEW = true;
  private static final boolean DEFAULT_STASH_INCLUDE_EXISTING_ISSUES = false;
  private static final int DEFAULT_STASH_FILES_IN_OVERVIEW = 0;

// Path: src/main/java/org/sonar/plugins/stash/issue/StashDiffReport.java
// public class StashDiffReport {
// 
//   public static final int VICINITY_RANGE_NONE = 0;
// 
//   private List<StashDiff> diffs;
// 
//   public StashDiffReport() {
//     this.diffs = new ArrayList<>();
//   }
// 
//   public List<StashDiff> getDiffs() {
//     return Collections.unmodifiableList(diffs);
//   }
// 
//   public void add(StashDiff diff) {
//     diffs.add(diff);
//   }
// 
//   public void add(StashDiffReport report) {
//     diffs.addAll(report.getDiffs());
//   }
// 
//   private static boolean inVicinityOfChangedDiff(StashDiff diff, long destination, int range) {
//     if (range <= 0) {
//       return false;
//     }
//     long lower = Math.min(diff.getSource(), diff.getDestination());
//     long upper = Math.max(diff.getSource(), diff.getDestination());
//     return Range.closed(lower - range, upper + range).contains(destination);
//   }
// 
//   private static boolean isChangedDiff(StashDiff diff, long destination) {
//     return diff.getDestination() == destination;
//   }
// 
//   private static boolean lineIsChangedDiff(StashDiff diff) {
//     return !diff.getType().equals(IssueType.CONTEXT);
//   }
// 
//   public IssueType getType(String path, long destination, int vicinityRange) {
//     boolean isInContextDiff = false;
//     for (StashDiff diff : diffs) {
//       if (Objects.equals(diff.getPath(), path)) {
//         // Line 0 never belongs to Stash Diff view.
//         // It is a global comment with a type set to CONTEXT.
//         if (destination == 0) {
//           return IssueType.CONTEXT;
//         } else if (!lineIsChangedDiff(diff)) {
//           // We only care about changed diff
//           continue;
//         } else if (isChangedDiff(diff, destination)) {
//           return diff.getType();
//         } else if (inVicinityOfChangedDiff(diff, destination, vicinityRange)) {
//           isInContextDiff = true;
//         }
//       }
//     }
//     return isInContextDiff ? IssueType.CONTEXT : null;
//   }
// 
//   /**
//    * Depends on the type of the diff.
//    * If type == "CONTEXT", return the source line of the diff.
//    * If type == "ADDED", return the destination line of the diff.
//    */
//   public long getLine(String path, long destination) {
//     for (StashDiff diff : diffs) {
//       if (Objects.equals(diff.getPath(), path) && (diff.getDestination() == destination)) {
// 
//         if (diff.getType() == IssueType.CONTEXT) {
//           return diff.getSource();
//         } else {
//           return diff.getDestination();
//         }
//       }
//     }
//     return 0;
//   }
// 
//   public StashDiff getDiffByComment(long commentId) {
//     for (StashDiff diff : diffs) {
//       if (diff.containsComment(commentId)) {
//         return diff;
//       }
//     }
//     return null;
//   }
// 
//   /**
//    * Get all comments from the Stash differential report.
//    */
//   public List<StashComment> getComments() {
//     List<StashComment> result = new ArrayList<>();
// 
//     for (StashDiff diff : this.diffs) {
//       List<StashComment> comments = diff.getComments();
// 
//       for (StashComment comment : comments) {
//         if (!result.contains(comment)) {
//           result.add(comment);
//         }
//       }
//     }
//     return result;
//   }
// }


// Path: src/main/java/org/sonar/plugins/stash/StashPlugin.java
import com.google.common.collect.Lists;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.sonar.api.Plugin;
import org.sonar.api.Properties;
import org.sonar.api.Property;
import org.sonar.api.PropertyType;
import org.sonar.api.batch.rule.Severity;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.resources.Qualifiers;
import java.util.List;
import org.sonar.plugins.stash.issue.StashDiffReport;

package org.sonar.plugins.stash;



@Properties({
                @Property(key = StashPlugin.STASH_NOTIFICATION,
                          name = "Stash Notification",
                          defaultValue = "false",
                          description = "Analysis result will be issued in Stash pull request",
                          global = false),
                @Property(key = StashPlugin.STASH_PROJECT,
                          name = "Stash Project",
                          description = "Stash project of current pull-request",
                          global = false),
                @Property(key = StashPlugin.STASH_REPOSITORY,
                          name = "Stash Repository",
                          description = "Stash project of current pull-request",
                          global = false),
                @Property(key = StashPlugin.STASH_PULL_REQUEST_ID,
                          name = "Stash Pull-request Id",
                          description = "Stash pull-request Id",
                          global = false)})

public class StashPlugin implements Plugin {

  private static final String DEFAULT_STASH_TIMEOUT_VALUE = "10000";
  private static final String DEFAULT_STASH_THRESHOLD_VALUE = "100";
  private static final boolean DEFAULT_STASH_ANALYSIS_OVERVIEW = true;
  private static final boolean DEFAULT_STASH_INCLUDE_EXISTING_ISSUES = false;
  private static final int DEFAULT_STASH_FILES_IN_OVERVIEW = 0;

  private static final int DEFAULT_STASH_INCLUDE_VICINITY_RANGE = StashDiffReport.VICINITY_RANGE_NONE;
