package org.jetbrains.plugins.textmate.regex;

import com.google.common.base.Preconditions;
import com.intellij.openapi.util.TextRange;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joni.Region;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

public class MatchData {
  public static final MatchData NOT_MATCHED = new MatchData(false, Collections.emptyList());

  private final boolean matched;
  private final List<TextRange> offsets;

  private MatchData(boolean matched, List<TextRange> offsets) {
    this.matched = matched;
    this.offsets = offsets;
  }

  public static MatchData fromRegion(@Nullable Region matchedRegion) {
    if (matchedRegion != null) {
      List<TextRange> offsets = new ArrayList<>(matchedRegion.numRegs);
      for (int i = 0; i < matchedRegion.numRegs; i++) {
        offsets.add(i, TextRange.create(Math.max(matchedRegion.beg[i], 0), Math.max(matchedRegion.end[i], 0)));
      }
      return new MatchData(true, offsets);
    }
    return NOT_MATCHED;
  }

  public int count() {
    return offsets.size();
  }

  public TextRange byteOffset() {
    return byteOffset(0);
  }

  @NotNull
  public TextRange byteOffset(int group) {
    Preconditions.checkElementIndex(group, offsets.size());
    return offsets.get(group);
  }

  public TextRange charOffset(byte[] stringBytes) {
    return charOffset(stringBytes, 0);
  }

  @NotNull
  public TextRange charOffset(byte[] stringBytes, int group) {
    return RegexUtil.charRangeByByteRange(stringBytes, byteOffset(group));
  }

  public boolean matched() {
    return matched;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    MatchData matchData = (MatchData)o;

    if (matched != matchData.matched) return false;
    if (!Objects.equals(offsets, matchData.offsets)) return false;

    return true;
  }

  @Override
  public int hashCode() {
    int result = (matched ? 1 : 0);
    result = 31 * result + (offsets != null ? offsets.hashCode() : 0);
    return result;
  }

  @Override
  public String toString() {
    return "{ matched=" + matched +
           ", offsets=" + offsets +
           '}';
  }
}

@@ -265,90 +265,8 @@
 rray
-List;%0Aimport java.util.Collections;%0Aimport java.util.List;%0Aimport java.util.Object
 s;%0A%0A
@@ -361,31 +361,29 @@
 se, 
-Collections.emptyList()
+TextRange.EMPTY_ARRAY
 );%0A%0A
@@ -415,16 +415,27 @@
 atched;%0A
+  @NotNull%0A
   privat
@@ -442,21 +442,16 @@
 e final 
-List%3C
 TextRang
@@ -443,33 +443,34 @@
  final TextRange
-%3E
+%5B%5D
  offsets;%0A%0A  pri
@@ -501,21 +501,25 @@
 atched, 
-List%3C
+@NotNull 
 TextRang
@@ -511,33 +511,34 @@
 otNull TextRange
-%3E
+%5B%5D
  offsets) %7B%0A    
@@ -704,21 +704,16 @@
 %7B%0A      
-List%3C
 TextRang
@@ -713,17 +713,18 @@
 extRange
-%3E
+%5B%5D
  offsets
@@ -734,20 +734,18 @@
 new 
-ArrayList%3C%3E(
+TextRange%5B
 matc
@@ -761,17 +761,17 @@
 .numRegs
-)
+%5D
 ;%0A      
@@ -839,15 +839,13 @@
 sets
-.add(i,
+%5Bi%5D =
  Tex
@@ -927,17 +927,16 @@
 %5Bi%5D, 0))
-)
 ;%0A      
@@ -1057,22 +1057,22 @@
 offsets.
-size()
+length
 ;%0A  %7D%0A%0A 
@@ -1244,14 +1244,14 @@
 ets.
-size()
+length
 );%0A 
@@ -1271,19 +1271,15 @@
 sets
-.get(
+%5B
 group
-)
+%5D
 ;%0A  
@@ -1831,22 +1831,21 @@
    if (!
-Object
+Array
 s.equals
@@ -1957,20 +1957,19 @@
     
-int result =
+return 31 *
  (ma
@@ -1986,98 +1986,35 @@
 : 0)
-;%0A    result = 31 * result + (offsets != null ? offsets.hashCode() : 0);%0A    return result
+ + Arrays.hashCode(offsets)
 ;%0A  
@@ -2092,27 +2092,16 @@
 atched +
-%0A          
  %22, offs
@@ -2112,28 +2112,34 @@
 %22 + 
+Arrays.toString(
 offsets
+)
  +
-%0A          
  '%7D'

convert list to array