/*
 * Copyright (c) 2011 Google Inc.
 *
 * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
 * Public License v1.0 which accompanies this distribution, and is available at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 */
package com.google.eclipse.protobuf.ui.util.editor;

import static com.google.common.collect.Lists.newArrayList;
import static com.google.eclipse.protobuf.ui.util.IStatusFactory.error;
import static com.google.eclipse.protobuf.ui.util.editor.Messages.*;
import static org.eclipse.compare.rangedifferencer.RangeDifferencer.findDifferences;
import static org.eclipse.core.filebuffers.FileBuffers.createTextFileBufferManager;
import static org.eclipse.core.runtime.Status.OK_STATUS;
import static org.eclipse.core.runtime.SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK;

import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.log4j.Logger;
import org.eclipse.compare.rangedifferencer.RangeDifference;
import org.eclipse.core.filebuffers.*;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.text.*;

import com.google.inject.Singleton;

/**
 * Utility methods related to editors. Adapted from CDT's
 * {@code org.eclipse.cdt.internal.ui.util.EditorUtility}.
 *
 * @author alruiz@google.com (Alex Ruiz)
 */
@Singleton public class ChangedLineRegionCalculator {
  private static Logger logger = Logger.getLogger(ChangedLineRegionCalculator.class);

  public IRegion[] calculateChangedLineRegions(final ITextFileBuffer buffer, final IDocument current,
      final IProgressMonitor monitor) throws CoreException {
    final AtomicReference<IRegion[]> result = new AtomicReference<IRegion[]>();
    final AtomicReference<IStatus> errorStatus = new AtomicReference<IStatus>(OK_STATUS);
    try {
      SafeRunner.run(new ISafeRunnable() {
        @Override public void handleException(Throwable exception) {
          logger.error(exception.getMessage(), exception);
          errorStatus.set(error(errorCalculatingChangedRegions, exception));
          result.set(null);
        }

        @Override public void run() throws Exception {
          monitor.beginTask(calculatingChangedRegions, 20);
          IFileStore fileStore = buffer.getFileStore();
          ITextFileBufferManager fileBufferManager = createTextFileBufferManager();
          fileBufferManager.connectFileStore(fileStore, getSubProgressMonitor(monitor, 15));
          try {
            IDocument old = ((ITextFileBuffer) fileBufferManager.getFileStoreFileBuffer(fileStore)).getDocument();
            result.set(getChangedLineRegions(old));
          } finally {
            fileBufferManager.disconnectFileStore(fileStore, getSubProgressMonitor(monitor, 5));
            monitor.done();
          }
        }

        /*
         * Returns regions of all lines which differ comparing {@code old}s content with {@code current}s content.
         * Successive lines are merged into one region.
         */
        private IRegion[] getChangedLineRegions(IDocument old) {
          RangeDifference[] differences = differencesWith(old);
          List<IRegion> regions = newArrayList();
          int numberOfLines = current.getNumberOfLines();
          for (RangeDifference difference : differences) {
            if (difference.kind() == RangeDifference.CHANGE) {
              int startLine = Math.min(difference.rightStart(), numberOfLines - 1);
              int endLine = difference.rightEnd() - 1;
              IRegion startLineRegion;
              try {
                startLineRegion = current.getLineInformation(startLine);
                if (startLine >= endLine) {
                  // startLine > endLine indicates a deletion of one or more lines.
                  // Deletions are ignored except at the end of the document.
                  if (startLine == endLine
                      || startLineRegion.getOffset() + startLineRegion.getLength() == current.getLength()) {
                    regions.add(startLineRegion);
                  }
                  continue;
                }
                IRegion endLineRegion = current.getLineInformation(endLine);
                int startOffset = startLineRegion.getOffset();
                int endOffset = endLineRegion.getOffset() + endLineRegion.getLength();
                regions.add(new Region(startOffset, endOffset - startOffset));
              } catch (BadLocationException e) {
                logger.error(e.getMessage(), e);
              }
            }
          }
          return regions.toArray(new IRegion[regions.size()]);
        }

        private RangeDifference[] differencesWith(IDocument old) {
          return findDifferences(new LineComparator(old), new LineComparator(current));
        }
      });
    } finally {
      IStatus status = errorStatus.get();
      if (!status.isOK()) {
        throw new CoreException(status);
      }
    }
    return result.get();
  }

  private static IProgressMonitor getSubProgressMonitor(IProgressMonitor monitor, int ticks) {
    if (monitor != null) {
      return new SubProgressMonitor(monitor, ticks, PREPEND_MAIN_LABEL_TO_SUBTASK);
    }
    return new NullProgressMonitor();
  }
}
