package com.intellij.vcs.log.ui;

import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.util.PairFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.data.*;
import com.intellij.vcs.log.graph.ChangeCursorActionRequest;
import com.intellij.vcs.log.graph.ClickGraphAction;
import com.intellij.vcs.log.graph.*;
import com.intellij.vcs.log.impl.VcsLogImpl;
import com.intellij.vcs.log.ui.frame.MainFrame;
import com.intellij.vcs.log.ui.frame.VcsLogGraphTable;
import com.intellij.vcs.log.ui.tables.AbstractVcsLogTableModel;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import java.awt.*;
import java.util.Collection;

public class VcsLogUiImpl implements VcsLogUi, Disposable {

  public static final String POPUP_ACTION_GROUP = "Vcs.Log.ContextMenu";
  public static final String TOOLBAR_ACTION_GROUP = "Vcs.Log.Toolbar";
  public static final String VCS_LOG_TABLE_PLACE = "Vcs.Log.ContextMenu";

  private static final Logger LOG = Logger.getInstance(VcsLogUiImpl.class);

  @NotNull private final MainFrame myMainFrame;
  @NotNull private final Project myProject;
  @NotNull private final VcsLogColorManager myColorManager;
  @NotNull private final VcsLogFilterer myFilterer;
  @NotNull private final VcsLog myLog;
  @NotNull private final VcsLogUiProperties myUiProperties;

  @NotNull private final Collection<VcsLogFilterChangeListener> myFilterChangeListeners = ContainerUtil.newArrayList();

  @NotNull private DataPack myDataPack;

  public VcsLogUiImpl(@NotNull VcsLogDataHolder logDataHolder, @NotNull Project project, @NotNull VcsLogSettings settings,
                      @NotNull VcsLogColorManager manager, @NotNull VcsLogUiProperties uiProperties, @NotNull DataPack initialDataPack) {
    myProject = project;
    myColorManager = manager;
    myUiProperties = uiProperties;
    myDataPack = initialDataPack;
    Disposer.register(logDataHolder, this);

    myFilterer = new VcsLogFilterer(logDataHolder, this);
    myLog = new VcsLogImpl(logDataHolder, this);
    myMainFrame = new MainFrame(logDataHolder, this, project, settings, uiProperties, myLog, initialDataPack);
  }

  @NotNull
  public MainFrame getMainFrame() {
    return myMainFrame;
  }

  public void jumpToRow(final int rowIndex) {
    UIUtil.invokeLaterIfNeeded(new Runnable() {
      @Override
      public void run() {
        myMainFrame.getGraphTable().jumpToRow(rowIndex);
      }
    });
  }

  public void setModel(@NotNull AbstractVcsLogTableModel newModel, @NotNull DataPack newDataPack,
                       @NotNull TIntHashSet previouslySelectedCommits) {
    final VcsLogGraphTable table = getTable();
    table.setModel(newModel);
    restoreSelection(newModel, newDataPack, previouslySelectedCommits, table);
    table.setPaintBusy(false);
  }

  private static void restoreSelection(@NotNull AbstractVcsLogTableModel newModel,
                                       @NotNull DataPack newDataPack,
                                       @NotNull TIntHashSet previouslySelectedCommits,
                                       @NotNull final VcsLogGraphTable table) {
    TIntHashSet rowsToSelect = findNewRowsToSelect(newModel, newDataPack, previouslySelectedCommits);
    rowsToSelect.forEach(new TIntProcedure() {
      @Override
      public boolean execute(int row) {
        table.addRowSelectionInterval(row, row);
        return true;
      }
    });
  }

  @NotNull
  private static TIntHashSet findNewRowsToSelect(@NotNull AbstractVcsLogTableModel newModel,
                                                 @NotNull DataPack dataPack,
                                                 @NotNull TIntHashSet selectedHashes) {
    TIntHashSet rowsToSelect = new TIntHashSet();
    if (newModel.getRowCount() == 0) {
      // this should have been covered by facade.getVisibleCommitCount,
      // but if the table is empty (no commits match the filter), the GraphFacade is not updated, because it can't handle it
      // => it has previous values set.
      return rowsToSelect;
    }
    GraphFacade facade = dataPack.getGraphFacade();
    for (int row = 0; row < facade.getVisibleCommitCount()
                      && rowsToSelect.size() < selectedHashes.size(); row++) { //stop iterating if found all hashes
      int commit = facade.getCommitAtRow(row);
      if (selectedHashes.contains(commit)) {
        rowsToSelect.add(row);
      }
    }
    return rowsToSelect;
  }

  public void repaintUI() {
    myMainFrame.getGraphTable().repaint();
  }

  public void showAll() {
    runUnderModalProgress("Expanding linear branches...", new Runnable() {
      @Override
      public void run() {
        final GraphAnswer answer = myDataPack.getGraphFacade().performAction(LinearBranchesExpansionAction.EXPAND);
        UIUtil.invokeAndWaitIfNeeded(new Runnable() {
          @Override
          public void run() {
            handleAnswer(answer);
          }
        });
      }
    });
  }

  public void hideAll() {
    runUnderModalProgress("Collapsing linear branches...", new Runnable() {
      @Override
      public void run() {
        final GraphAnswer answer = myDataPack.getGraphFacade().performAction(LinearBranchesExpansionAction.COLLAPSE);
        UIUtil.invokeAndWaitIfNeeded(new Runnable() {
          @Override
          public void run() {
            handleAnswer(answer);
          }
        });
      }
    });
  }

  public void setLongEdgeVisibility(boolean visibility) {
    handleAnswer(myDataPack.getGraphFacade().performAction(LongEdgesAction.valueOf(visibility)));
    myUiProperties.setLongEdgesVisibility(visibility);
  }

  public boolean areLongEdgesHidden() {
    return myDataPack.getGraphFacade().getInfoProvider().areLongEdgesHidden();
  }

  public void setBek(boolean bek) {
    myUiProperties.setBek(bek);
    final BekGraphAction bekGraphAction = new BekGraphAction(bek ? PermanentGraph.SortType.Bek : PermanentGraph.SortType.Normal);
    runUnderModalProgress("Apply sort type...", new Runnable() {
      @Override
      public void run() {
        final GraphAnswer answer = myDataPack.getGraphFacade().performAction(bekGraphAction);
        UIUtil.invokeLaterIfNeeded(new Runnable() {
          @Override
          public void run() {
            handleAnswer(answer);
          }
        });
      }
    });
  }

  public boolean isBek() {
    return myUiProperties.isBek();
  }

  public void click(int rowIndex) {
    handleAnswer(myDataPack.getGraphFacade().performAction(new ClickGraphAction(rowIndex, null)));
  }

  public void jumpToCommit(@NotNull Hash commitHash) {
    jumpTo(commitHash, new PairFunction<AbstractVcsLogTableModel, Hash, Integer>() {
      @Override
      public Integer fun(AbstractVcsLogTableModel model, Hash hash) {
        return model.getRowOfCommit(hash);
      }
    });
  }

  public void jumpToCommitByPartOfHash(@NotNull String commitHash) {
    jumpTo(commitHash, new PairFunction<AbstractVcsLogTableModel, String, Integer>() {
      @Override
      public Integer fun(AbstractVcsLogTableModel model, String hash) {
        return model.getRowOfCommitByPartOfHash(hash);
      }
    });
  }

  public void handleAnswer(@Nullable GraphAnswer answer) {
    repaintUI();

    if (answer == null) {
      return;
    }
    GraphChange graphChange = answer.getGraphChange();
    if (graphChange != null) {
      ((AbstractTableModel)(getTable().getModel())).fireTableStructureChanged();
    }

    GraphActionRequest actionRequest = answer.getActionRequest();
    if (actionRequest instanceof JumpToRowActionRequest) {
      int row = ((JumpToRowActionRequest)actionRequest).getRow();
      jumpToRow(row);
    }
    else if (actionRequest instanceof ChangeCursorActionRequest) {
      myMainFrame.getGraphTable().setCursor(((ChangeCursorActionRequest)actionRequest).getCursor());
    }
  }

  private <T> void jumpTo(@NotNull final T commitId, @NotNull final PairFunction<AbstractVcsLogTableModel, T, Integer> rowGetter) {
    AbstractVcsLogTableModel model = getModel();
    if (model == null) {
      return;
    }

    int row = rowGetter.fun(model, commitId);
    if (row >= 0) {
      jumpToRow(row);
    }
    else if (model.canRequestMore()) {
      model.requestToLoadMore(new Runnable() {
        @Override
        public void run() {
          jumpTo(commitId, rowGetter);
        }
      });
    }
    else {
      commitNotFound(commitId.toString());
    }
  }

  @Nullable
  private AbstractVcsLogTableModel getModel() {
    TableModel model = getTable().getModel();
    if (model instanceof AbstractVcsLogTableModel) {
      return (AbstractVcsLogTableModel)model;
    }
    showMessage(MessageType.WARNING, "The log is not ready to search yet");
    return null;
  }

  private void showMessage(@NotNull MessageType messageType, @NotNull String message) {
    LOG.info(message);
    VcsBalloonProblemNotifier.showOverChangesView(myProject, message, messageType);
  }

  private void commitNotFound(@NotNull String commitHash) {
    if (getFilters().isEmpty()) {
      showMessage(MessageType.WARNING, "Commit " + commitHash + " not found");
    }
    else {
      showMessage(MessageType.WARNING, "Commit " + commitHash + " doesn't exist or doesn't match the active filters");
    }
  }

  @NotNull
  public VcsLogColorManager getColorManager() {
    return myColorManager;
  }

  @NotNull
  public VcsLogFilterer getFilterer() {
    return myFilterer;
  }

  @NotNull 
  public TIntHashSet getSelectedCommits() {
    int[] selectedRows = getTable().getSelectedRows();
    return getCommitsAtRows(myDataPack.getGraphFacade(), selectedRows);
  } 
  
  @NotNull
  private static TIntHashSet getCommitsAtRows(@NotNull GraphFacade facade, int[] rows) {
    TIntHashSet commits = new TIntHashSet();
    for (int row : rows) {
      int commit = facade.getCommitAtRow(row);
      if (commit > 0) {
        commits.add(commit);
      }
    }
    return commits;
  }

  public void setDataPack(@NotNull DataPack dataPack) {
    applyFiltersAndUpdateUi(dataPack);
  }

  private void applyFiltersAndUpdateUi(@NotNull final DataPack dataPack) {
    runUnderModalProgress("Applying filters...", new Runnable() {
      public void run() {
        final TIntHashSet previouslySelected = getSelectedCommits();
        final AbstractVcsLogTableModel newModel = myFilterer.applyFiltersAndUpdateUi(dataPack, getFilters());
        UIUtil.invokeAndWaitIfNeeded(new Runnable() {
          @Override
          public void run() {
            myDataPack = dataPack;
            setModel(newModel, myDataPack, previouslySelected);
            myMainFrame.updateDataPack(myDataPack);
            setLongEdgeVisibility(myUiProperties.areLongEdgesVisible());
            myDataPack.getGraphFacade().performAction(new BekGraphAction(myUiProperties.isBek() ?
                                                                         PermanentGraph.SortType.Bek : PermanentGraph.SortType.Normal));
            fireFilterChangeEvent();
            repaintUI();

            if (newModel.getRowCount() == 0) { // getValueAt won't be called for empty model => need to explicitly request to load more
              newModel.requestToLoadMore(EmptyRunnable.INSTANCE);
            }
          }
        });
      }
    });
  }

  public void applyFiltersAndUpdateUi() {
    ApplicationManager.getApplication().assertIsDispatchThread();
    applyFiltersAndUpdateUi(myDataPack);
  }

  @NotNull
  public VcsLogFilterCollection getFilters() {
    return myMainFrame.getFilterUi().getFilters();
  }

  public VcsLogGraphTable getTable() {
    return myMainFrame.getGraphTable();
  }

  @NotNull
  public Project getProject() {
    return myProject;
  }

  public void runUnderModalProgress(@NotNull final String task, @NotNull final Runnable runnable) {
    getTable().executeWithoutRepaint(new Runnable() {
      public void run() {
        ProgressManager.getInstance().runProcessWithProgressSynchronously(runnable, task, false, null, getMainFrame().getMainComponent());
      }
    });
    repaintUI();
  }

  public void setBranchesPanelVisible(boolean visible) {
    myMainFrame.setBranchesPanelVisible(visible);
  }

  public Component getToolbar() {
    return myMainFrame.getToolbar();
  }

  @NotNull
  public VcsLog getVcsLog() {
    return myLog;
  }

  @NotNull
  @Override
  public VcsLogFilterUi getFilterUi() {
    return myMainFrame.getFilterUi();
  }

  @Override
  @NotNull
  public DataPack getDataPack() {
    ApplicationManager.getApplication().assertIsDispatchThread();
    return myDataPack;
  }

  @Override
  public void addHighlighter(@NotNull VcsLogHighlighter highlighter) {
    getTable().addHighlighter(highlighter);
    repaintUI();
  }

  @Override
  public void removeHighlighter(@NotNull VcsLogHighlighter highlighter) {
    getTable().removeHighlighter(highlighter);
    repaintUI();
  }

  @Override
  public void addFilterChangeListener(@NotNull VcsLogFilterChangeListener listener) {
    myFilterChangeListeners.add(listener);
  }

  @Override
  public void removeFilterChangeListener(@NotNull VcsLogFilterChangeListener listener) {
    myFilterChangeListeners.remove(listener);
  }

  private void fireFilterChangeEvent() {
    for (VcsLogFilterChangeListener listener : myFilterChangeListeners) {
      listener.filtersPossiblyChanged();
    }
  }

  @Override
  public void dispose() {
    getTable().removeAllHighlighters();
  }

}
