code: /* LanguageTool, a natural language style checker
   * Copyright (C) 2017 Daniel Naber (http://www.danielnaber.de)
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
   * USA
   */
  package org.languagetool.server;
  
  import org.languagetool.Tag;
  import org.languagetool.rules.RuleMatch;
  
  import java.util.Collections;
  import java.util.List;
  import java.util.Objects;
  import java.util.Optional;
  
  /**
   * A potential error as returned by the HTTP API of LanguageTool.
   * @since 4.0
   */
  class RemoteRuleMatch {
  
    private final String ruleId;
    private final String msg;
    private final String context;
    private final int contextOffset;
    private final int offset;
    private final int errorLength;
    private final int estimatedContextForSureMatch;
  
    private String subId;
    private String shortMsg;
    private List<String> replacements;
    private String url;
    private String category;
    private String categoryId;
    private String locQualityIssueType;
    private List<Tag> tags;
  
    RemoteRuleMatch(String ruleId, String msg, String context, int contextOffset, int offset, int errorLength) {
      this(ruleId, msg, context, contextOffset, offset, errorLength, 0);
    }
    
    RemoteRuleMatch(String ruleId, String msg, String context, int contextOffset, int offset, int errorLength,
                    int estimatedContextForSureMatch) {
      this.ruleId = Objects.requireNonNull(ruleId);
      this.msg = Objects.requireNonNull(msg);
      this.context = Objects.requireNonNull(context);
      this.contextOffset = contextOffset;
      this.offset = offset;
      this.errorLength = errorLength;
      this.estimatedContextForSureMatch = estimatedContextForSureMatch;
    }
  
    boolean isTouchedByOneOf(List<RuleMatch> matches) {
      for (RuleMatch match : matches) {
        if (offset <= match.getToPos() && offset + errorLength >= match.getFromPos()) {
          return true;
        }
      }
      return false;
    }
  
    /** Unique (per language) identifier for the error. */
    public String getRuleId() {
      return ruleId;
    }
  
    /** Optional sub id (rule groups have a sub id for each rule). */
    public Optional<String> getRuleSubId() {
      return Optional.ofNullable(subId);
    }
  
    /** A text describing the error to the user. */
    public String getMessage() {
      return msg;
    }
  
    /** Optional short message describing the error. */
    public Optional<String> getShortMessage() {
      return Optional.ofNullable(shortMsg);
    }
  
    /**
     * Potential corrections for the error. Note that corrections might be wrong and
     * they are not necessarily ordered by quality.
     */
    public Optional<List<String>> getReplacements() {
      return Optional.ofNullable(replacements);
    }
  
    /** The error in its context. See {@link #getContextOffset()} and {@link #getErrorLength()} to get the exact position. */
    public String getContext() {
      return context;
    }
    
    /** The character position of the error start inside the result of {@link #getContext()}. */
    public int getContextOffset() {
      return contextOffset;
    }
    
    /** The character position where the error starts. */
    public int getErrorOffset() {
      return offset;
    }
    
    /** The length of the error in characters. */
    public int getErrorLength() {
      return errorLength;
    }
  
    /** URL with a more detailed explanation of the error. */
    public Optional<String> getUrl() {
      return Optional.ofNullable(url);
    }
  
    /** The error's category. */
    public Optional<String> getCategory() {
      return Optional.of(category);
    }
  
    /** The id of the error's category. */
    public Optional<String> getCategoryId() {
      return Optional.of(categoryId);
    }
  
    public Optional<String> getLocQualityIssueType() {
      return Optional.ofNullable(locQualityIssueType);
    }
  
    /** @since 5.3 */
    public List<Tag> getTags() {
      return tags;
    }
  
    //
    // non-public setters
    //
    
    void setRuleSubId(String subId) {
      this.subId = subId;
    }
  
    void setShortMsg(String shortMsg) {
      this.shortMsg = shortMsg;
    }
  
    void setReplacements(List<String> replacements) {
      this.replacements = Collections.unmodifiableList(replacements);
    }
  
    void setUrl(String url) {
      this.url = url;
    }
  
    void setCategory(String category) {
      this.category = category;
    }
  
    void setCategoryId(String categoryId) {
      this.categoryId = categoryId;
    }
  
    void setLocQualityIssueType(String locQualityIssueType) {
      this.locQualityIssueType = locQualityIssueType;
    }
  
    void setTags(List<Tag> tags) {
      this.tags = tags;
    }
  
    int estimatedContextForSureMatch() {
      return estimatedContextForSureMatch;
    }
  
    @Override
    public String toString() {
      return ruleId + "@" + offset + "-" + (offset + errorLength);
    }
  
  }
  