/*
 * Copyright 2013-2014 Urs Wolfer
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.urswolfer.intellij.plugin.gerrit.ui.diff;

import com.google.common.base.Throwables;
import com.google.gerrit.extensions.client.Comment;
import com.intellij.util.text.CharSequenceReader;

import java.io.BufferedReader;
import java.io.IOException;

/**
 * @author Urs Wolfer
 */
public final class RangeUtils {

    private RangeUtils() {}

    public static Comment.Range textOffsetToRange(CharSequence charsSequence, int start, int end) {
        int startLine = 1;
        int startOffset = -1;
        int endLine = 1;
        int endOffset = -1;
        try {
            BufferedReader reader = new BufferedReader(new CharSequenceReader(charsSequence));
            String lineString;
            int currentCharCount = 0;
            while ((lineString = reader.readLine()) != null) {
                currentCharCount += lineString.length();
                currentCharCount++; // line break

                if (start > currentCharCount) {
                    startLine++;
                } else if (startOffset < 0) {
                    startOffset = start - (currentCharCount - lineString.length() - 1);
                }

                if (end > currentCharCount) {
                    endLine++;
                } else if (endOffset < 0) {
                    endOffset = end - (currentCharCount - lineString.length() - 1);
                    break;
                }
            }
        } catch (IOException e) {
            throw Throwables.propagate(e);
        }

        Comment.Range range = new Comment.Range();
        range.startLine = startLine;
        range.startCharacter = startOffset;
        range.endLine = endLine;
        range.endCharacter = endOffset;
        return range;
    }

    public static Offset rangeToTextOffset(CharSequence charsSequence, Comment.Range range) {
        int startOffset = 0;
        int endOffset = 0;
        try {
            BufferedReader reader = new BufferedReader(new CharSequenceReader(charsSequence));
            String line;
            int textLineCount = 1;
            while ((line = reader.readLine()) != null) {
                if (textLineCount < range.startLine) {
                    startOffset += line.length();
                    startOffset++; // line break
                }
                if (textLineCount < range.endLine) {
                    endOffset += line.length();
                    endOffset++; // line break
                } else {
                    break;
                }
                textLineCount++;
            }
        } catch (IOException e) {
            throw Throwables.propagate(e);
        }
        startOffset += range.startCharacter;
        endOffset += range.endCharacter;
        return new Offset(startOffset, endOffset);
    }

    public static class Offset {
        public int start;
        public int end;

        public Offset(int start, int end) {
            this.start = start;
            this.end = end;
        }
    }
}

@@ -1143,32 +1143,119 @@
 endOffset = -1;%0A
+        CharSequenceReader charSequenceReader = new CharSequenceReader(charsSequence);%0A
         try %7B%0A  
@@ -1299,37 +1299,33 @@
  BufferedReader(
-new C
+c
 harSequenceReade
@@ -1321,39 +1321,24 @@
 quenceReader
-(charsSequence)
 );%0A         
@@ -2144,32 +2144,92 @@
 te(e);%0A        %7D
+ finally %7B%0A            charSequenceReader.close();%0A        %7D
 %0A%0A        Commen
@@ -2590,32 +2590,119 @@
  endOffset = 0;%0A
+        CharSequenceReader charSequenceReader = new CharSequenceReader(charsSequence);%0A
         try %7B%0A  
@@ -2754,21 +2754,17 @@
 dReader(
-new C
+c
 harSeque
@@ -2772,31 +2772,16 @@
 ceReader
-(charsSequence)
 );%0A     
@@ -3398,32 +3398,92 @@
 s.propagate(e);%0A
+        %7D finally %7B%0A            charSequenceReader.close();%0A
         %7D%0A      
@@ -3620,31 +3620,24 @@
 %0A    %7D%0A%0A    
-public 
 static class
@@ -3650,30 +3650,29 @@
 t %7B%0A        
-public
+final
  int start;%0A
@@ -3679,22 +3679,21 @@
         
-public
+final
  int end
@@ -3703,23 +3703,16 @@
         
-public 
 Offset(i

fix minor issues detected by sonar